2

This is a bit descriptive so please bear with me. :)

In the application that I'm trying to build, there are distinct functionalities of product. Users can choose to opt-in for functionality A, B, D but not C. The way I'm building this, is that each of the distinct functionality is a Service (stateless, I'm thinking of storing the data in Azure SQL DBs and exposing REST APIs from each service). Bundled all services together is an ApplicationType. For each customer tenant (consider this as an shared account of a group of users) that is created, I'm thinking of creating a new concrete instance of registered ApplicationType using a TenantManagementService and calling client.ApplicationManager.CreateApplicationAsync() on a FabricClient instance so that I can have a dedicated application instance running on my nodes for that tenant. However, as I mentioned, a tenant can choose to opt-in only for specific functionality which is mapped to a subset of services. If a tenant chooses only service A of my Application, rest of the service instances corresponding to features B, C, D shouldn't be idly running on the nodes.

I thought of creating actors for each service, but the services I'm creating are stateless and I'd like to have multiple instances of them actively running on multiple nodes to load balance rather than having idle replicas of stateful services.

Similar to what I'm doing with application types, i.e., spawning application types as a new tenant registers, can I spawn/delete services as and when a tenant wants to opt-in/out of product features?

Here's what I've tried: I tried setting InstanceCount 0 for the services at when packaging my application. In my ApplicationParameters XML files:

<Parameters>
    <Parameter Name="FeatureAService_InstanceCount" Value="0" />
    <Parameter Name="FeatureBService_InstanceCount" Value="0" />
</Parameters>

However, Service Fabric Explorer cribs when instantiating the application out of such application type. The error is this: zero service instance count error

But on the other hand, when a service is deployed on the fabric, it gives me an option to delete it specifically, so this scenario should be valid. enter image description here

Any suggestions are welcome!

EDIT: My requirement is similar to the approach mentioned by anderso in here - https://stackoverflow.com/a/35248349/1842699, However, the problem that I'm specifically trying to solve is to upload create an application instance with one or more packaged services having zero instance count!

upInCloud
  • 979
  • 2
  • 10
  • 29
  • Did you see this article and sample about dynamic deployments? https://blogs.msdn.microsoft.com/premier_developer/2017/08/15/how-not-to-use-service-fabric-default-services/ https://github.com/dkj0/SFJobCreator – LoekD Jun 25 '18 at 14:31

3 Answers3

5

@uplnCloud

I hope I understand everything right.

Your situation is the following:

  • Each customer should have separate Application (created from the same ApplicationType).
  • Each customer should have only subset of Services (defined in ApplicationType).

If I get it right then this is supported out of the box.

First of all you should remove <DefaultServices /> section from the ApplicationManifest.xml. This will instruct Service Fabric to don't create services automatically with the application.

Now the algorithm is the following:

  1. Create application using FabricClient.ApplicationManager.CreateApplicationAsync()
  2. For each required feature create a new corresponding Service using FabricClient.ServiceManager.CreateServiceAsync() (you need to specify the Application name of newly created Application)

Also note that CreateServiceAsync() accepts ServiceDescriptor that you can configure all service related parameters - starting from partitioning schema and ending up with instance count.

Oleg Karasik
  • 959
  • 6
  • 17
  • Thank you guys for the help, I think that's what I need. Also, any comments on this architecture of having each application instance per tenant and bunch of service instances under each of application instance? How do you go about solving your problems? – upInCloud Jun 25 '18 at 14:21
  • 1
    @upInCloud I think this a good solution. Service Fabric was specifically designed in that way to allow that kind of scaling and composition. There is also one more important point here is that each of the Application instance is upgraded separately - so if your customer don't need updates anymore that is fine you simply wouldn't update his Application instance while you always would be able to keep upgrading the others. – Oleg Karasik Jun 26 '18 at 07:00
  • Thanks @Oleg Karasik it helps! – upInCloud Jun 26 '18 at 08:11
1

Unfortunately you can't have 0 instance services, Service Fabric has the idea that a named service always exists(running). In this case, when you define a service (give a name to a serviceType instance), it will have at least 1 instance running, otherwise, you shouldn't even have the definition of this service on your application if it does not need to be running.

But what you can have is the ServiceType definition, that means, you have the binaries but you will create it when required.

I assume you are being limited by the default services, where you declare the application and services structure upfront(before deployment of any application instance), instead, you should use dynamic service creation via FabricClient like you described, or via Powershell using New-ServiceFabricApplication and New-ServiceFabricService .

This link you guide you how to do it using FabricClient

Diego Mendes
  • 10,631
  • 2
  • 32
  • 36
1

I'll just add this as a new answer instead of commenting on another answer.

As other have mentioed, remove DefaultServices from your ApplicationManifest. That way, every new instance of the ApplicationType you create will come online without services, and you'll have to create those manually depending on what functionallity your customer has selected.

Also, going with the "services per customer" approach, make sure you got enough nodes to handle the load when you get customers online. You'll end up with a lot of processes (since Application Instances) runs their own processes of the services, and if you have few nodes with a lot of these, reboots to your cluster nodes can take a bit to stabilise since it can potentionally have many services it needs to relocate. Altough running Stateless Services will aleviate a good part of this.

anderso
  • 981
  • 8
  • 12
  • I agree on the high number of nodes part. On the similar lines, is this architecturally correct to spawn separate set of processes per tenant onboarded? I'm quite new to microservices world and hence it feels a bit weird and dangerous to do that :) – upInCloud Jun 26 '18 at 14:56
  • 2
    I don't think there's anything wrong, it just depends on what you want to accomplish. There's no real difference in having a service per customer or one service for all where you code in the parts required for customer seperation. We started with too many services per customer, and consolidated them into system wide services with a few per customer services that dealt with things that made sense having process isolation and such. It's a balance you'll have to find with what you want to acomplish and the amoint of resources you want to spend, both in coding time and HW costs – anderso Jun 26 '18 at 15:02
  • Got it, we currently have bunch of not-so-microservices in our product that each get deployed to a bunch of Azure VMs and talk to each other. I was thinking of splitting them further into finer services and deploying them per customer as we discussed. But knowing that you had the reverse journey makes me think more about this approach! – upInCloud Jun 26 '18 at 15:08
  • As long as they are stateless, the cost of combining or splitting them up at a later point should be pretty insignificant, so I'd say do either of the approaches, and then evaluate how it goes in X months and see if you and your operation people are happy with it. That's what we did, and ended up somewhere in the middle :) – anderso Jun 26 '18 at 15:11
  • Thanks a lot @anderso, it is always helpful to learn few things from experienced folks! – upInCloud Jun 26 '18 at 15:13