问题
I have an SF application type consisting of two service types – stateless WebApi Gateway service type and stateless Worker service type. I am creating one application instance with default Gateway service instance. The Gateway service instance creates Worker service instances dynamically on demand by using code like this (the client
variable is the System.Fabric.FabricClient
instance):
var serviceDescription = new StatefulServiceDescription()
{
ApplicationName = new Uri("fabric:/Gateway"),
ServiceName = new Uri("fabric:/Gateway/Worker-" + SomeUniqueWorkerId),
ServiceTypeName = "WorkerType",
HasPersistedState = true,
PartitionSchemeDescription = new UniformInt64RangePartitionSchemeDescription(),
MinReplicaSetSize = 1,
TargetReplicaSetSize = 1
};
await client.ServiceManager.CreateServiceAsync(serviceDescription);
When SF places two or more instances of the Worker service type onto one node, they all share the same process (i.e. Worker.exe). This is problematic because the different Worker service instances need to dynamically load different versions of assemblies from different file shares. Therefore, my question is:
Is it possible to force SF to host multiple service instances of the same type on one node in separate processes?
(I think that guest executables work that way.)
回答1:
You can now specify the ServicePackageActivationMode
when creating services.
With the default mode or with ServicePackageActivationMode set to "SharedProcess", all of these service objects would run in the same processes. However, by specifying ExclusiveProcess, each service object will end up created in its own process. Let's say that you had these two stateless services deployed on a simple 5 node cluster.
With the Shared|Default mode, you'd get 5 processes, one per node, each with 2 service objects running inside them. With the Exclusive mode, you get 10 processes, 2 per node, each with 1 service object running inside it.
New-ServiceFabricService -Stateless -PartitionSchemeSingleton -ApplicationName "fabric:/App" -ServiceName "fabric:/App/svc" -ServiceTypeName "T1" -InstanceCount -1 -ServicePackageActivationMode ExclusiveProcess
New-ServiceFabricService -Stateless -PartitionSchemeSingleton -ApplicationName "fabric:/App" -ServiceName "fabric:/App/svc" -ServiceTypeName "T2" -InstanceCount -1 -ServicePackageActivationMode ExclusiveProcess
In your example above, all you need to do is add
ServicePackageActivationMode = ServicePackageActivationMode.ExclusiveProcess
to your ServiceDescription.
This is a good piece of docs which goes into more detail about each model and how to choose which is right for a given situation. Most commonly I see it used to avoid sharing statics that can't be factored out of the service code and owned at the host process layer instead.
回答2:
This is by design, and it is not possible to run multiple service instances of the same type in separate processes on the the same node, today. We are working on making this an option, however.
For now, if you need process-level isolation, you have to use separate application instances. In your scenario, you can do this by separating the Web service and the Worker service into individual application types.
来源:https://stackoverflow.com/questions/41859980/service-fabric-process-isolation-for-dynamically-created-services-on-the-same-no