I'm trying to get a little follow up to this question that's already been answered...
Service Fabric multi-tenant
If I were to setup my tenants as Azure Service Fabric Stateless Services (they'll get their state out-of-band), how can I put more than one tenant on each node in the cluster? In testing, it seems that Service Fabric gags if you try and make your instance count greater than the node count.
These tenants are very lightweight, so I should be able to run dozens of them on each node (we will have hundreds overall), and I don't want to have to do a node for each one. Specifically, the tenants are more-or-less just opening a long-polling HTTP connection to an external customer service and streaming that data back into our system - so there's no public endpoints in play here. I just need the ability to spin up a lot of these workers that'll each open up their own long-polling connection.
Can somebody point me in the right direction?
FYI, I've explained a little bit more here... https://social.msdn.microsoft.com/Forums/en-US/efd172e2-0783-489b-b3ab-ec62fb7b8ee4/multiple-instances-per-node?forum=AzureServiceFabric
Thanks in advance!
Azure AD B2B collaboration enables users to use one set of credentials to sign in to multiple tenants.
Azure Service Fabric versions - Azure Service Fabric | Microsoft Learn. This browser is no longer supported. Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Azure Service Fabric mesh gives you a fully managed microservices platform. It enables businesses to easily build mission-critical, scalable applications using microservices with any code or framework of your choice.
A single Service Fabric node type/scale set can not contain more than 100 nodes/VMs. To scale a cluster beyond 100 nodes, add additional node types.
You'll need to somehow partition your service.
There is several options, but the two that aligns good here (and also with the SO question you linked are):
Have a SF application where each tenant gets an instance of your service. You will then need to have a shared service in front to route requests to the correct service. It should look something like this.
MyAwesomeApp
SharedStatelessApi <- External API points here
MyTenantService_Tenant1 <- ServiceType: MyTenantService
MyTenantService_Tenant2 <- ServiceType: MyTenantService
...
The other solution is to have one (or more) service fabric application per tenant, and would look something along the lines of:
MySharedApp
SharedStatelessApi <- External API points here
Tenant1 <- ApplicationType: MyTenantApp
MyTenantService <- ServiceType: MyTenantService
Tenant2 <- ApplicationType: MyTenantApp
MyTenantService <- ServiceType: MyTenantService
It's the same concept as the first example, but the partition is done on a higher lever.
Personally, I prefer the second case. It feels more right. In both cases, you'll have to either create the services/application manually when a new customer signs up, or do it in code. If you want to do it in code, you should look at the FabricClient. If you need an example of that, let me know.
Also, as you can see, you should have a shared public endpoint, and in that endpoint route the request to the correct service based on something (header, auth token, uri, whatever is inline with your app).
Example of using FabricClient to create a service:
First you need a FabricClient. For a unsecured cluster (your local dev cluster), the following is enough:
var fabricClient = new FabricClient("localhost:19000");
When you have deployed to a secured cluster (for example in Azure), you need to authenticate the FabricClient, like so:
var creds = new X509Credentials
{
FindType = X509FindType.FindByThumbprint,
FindValue = clientCertThumbprint,
RemoteCertThumbprints = {clientCertThumbprint},
StoreLocation = StoreLocation.LocalMachine,
StoreName = "My"
};
var clusterEndpoint = "CLUSTERNAME.LOCATION.cloudapp.azure.com:19000"
// or whatever your cluster endpoint is
var fabricClient = new FabricClient(creds, clusterEndpoint);
Then, when you have a FabricClient, you can create a stateless service like this:
var statelessDescriptor = new StatelessServiceDescription
{
ApplicationName = new Uri("fabric:/MYAPP"),
InstanceCount = 1, // How many instances.
PartitionSchemeDescription = new SingletonPartitionSchemeDescription(),
ServiceName = new Uri("fabric:/MYAPP/TenantA"),
ServiceTypeName = "YourServiceTypeName",
InitializationData = DATA_TO_PASS_TO_SERVICE_BYTE[] // Only if needed.
};
await _client.ServiceManager.CreateServiceAsync(statelessDescriptor)
If you passed any data in the "InitializationData" prop, it will be available in the service as ServiceInitializationParameters.InitializationData
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With