Azure Service Fabric 托管模型Azure Service Fabric hosting model

本文概述 Azure Service Fabric 提供的应用程序托管模型,并介绍共享进程模型和独占进程模型之间的差异。This article provides an overview of application hosting models provided by Azure Service Fabric, and describes the differences between the Shared Process and Exclusive Process models. 本文介绍已部署的应用程序在 Service Fabric 节点上的外观,以及服务和服务主机进程的副本(或实例)之间的关系。It describes how a deployed application looks on a Service Fabric node, and the relationship between replicas (or instances) of the service and the service-host process.

在继续阅读之前,请确保了解在 Service Fabric 中为应用程序建模中所述的各种概念及其相互关系。Before proceeding further, be sure that you understand the various concepts and relationships explained in Model an application in Service Fabric.


在本文中,除非明确说明,否则:In this article, unless explicitly mentioned as meaning something different:

  • “副本”指有状态服务的副本或无状态服务的实例。Replica refers to both a replica of a stateful service and an instance of a stateless service.
  • CodePackage 被视为与注册 ServiceTypeServiceHost 进程相同,并且 CodePackage 托管该 ServiceType 的服务副本。CodePackage is treated as equivalent to a ServiceHost process that registers a ServiceType, and hosts replicas of services of that ServiceType.

让我们通过示例来了解托管模型。To understand the hosting model, let's walk through an example. 假设有一个 ApplicationType 的“MyAppType”,它的 ServiceType 为“MyServiceType”。Let's say we have an ApplicationType 'MyAppType', which has a ServiceType 'MyServiceType'. “MyServiceType”由 ServicePackage“MyServicePackage”提供,此 ServicePackage 的 CodePackage 为“MyCodePackage”。'MyServiceType' is provided by the ServicePackage 'MyServicePackage', which has a CodePackage 'MyCodePackage'. “MyCodePackage”在运行时注册 ServiceType“MyServiceType”。'MyCodePackage' registers ServiceType 'MyServiceType' when it runs.

假设有三个节点群集,创建“MyAppType”类型的应用程序 fabric:/App1。Let's say we have a three-node cluster, and we create an application fabric:/App1 of type 'MyAppType'. 在此应用程序 fabric:/App1 中创建“MyServiceType”类型的服务 fabric:/App1/ServiceAInside this application fabric:/App1, we create a service fabric:/App1/ServiceA of type 'MyServiceType'. 该服务有 2 个分区(例如 P1P2),每个分区有 3 个副本。This service has two partitions (for example, P1 and P2), and three replicas per partition. 下图显示了此应用程序部署在节点后的视图。The following diagram shows the view of this application as it ends up deployed on a node.


Service Fabric 已激活启动了“MyServicePackage”的“MyCodePackage”,“MyServicePackage”正在托管两个分区中的副本。Service Fabric activated 'MyServicePackage', which started 'MyCodePackage', which is hosting replicas from both the partitions. 群集中的所有节点将都具有相同的视图,因为每个分区中选择的副本数与群集中的节点数相等。All the nodes in the cluster have the same view, because we chose the number of replicas per partition to be equal to the number of nodes in the cluster. 在应用程序 fabric:/App1 中创建另一个服务 fabric:/App1/ServiceBLet's create another service, fabric:/App1/ServiceB, in the application fabric:/App1. 该服务有 1 个分区(例如 P3),每个分区有 3 个副本。This service has one partition (for example, P3), and three replicas per partition. 下图显示节点上的新视图:The following diagram shows the new view on the node:


Service Fabric 将服务 fabric:/App1/ServiceBP3 分区的新副本放置在“MyServicePackage”的现有激活中。Service Fabric placed the new replica for partition P3 of service fabric:/App1/ServiceB in the existing activation of 'MyServicePackage'. 现在,Now. 创建另一个“MyAppType”类型的应用程序 fabric:/App2let's create another application fabric:/App2 of type 'MyAppType'. fabric:/App2 内部创建服务 fabric:/App2/ServiceAInside fabric:/App2, create a service fabric:/App2/ServiceA. 该服务有 2 个分区(P4P5),每个分区有 3 个副本。This service has two partitions (P4 and P5), and three replicas per partition. 下图显示了新的节点视图:The following diagram shows the new node view:


Service Fabric 激活了“MyServicePackage”的新副本,此“MyServicePackage”启动“MyCodePackage”的新副本。Service Fabric activates a new copy of 'MyServicePackage', which starts a new copy of 'MyCodePackage'. 服务 fabric:/App2/ServiceA 两个分区(P4P5)中的副本均放置在“MyCodePackage”的此新副本中。Replicas from both partitions of service fabric:/App2/ServiceA (P4 and P5) are placed in this new copy 'MyCodePackage'.

共享进程模型Shared Process model

上一部分描述了 Service Fabric 提供的默认托管模型,也称为共享进程模型。The preceding section describes the default hosting model provided by Service Fabric, referred to as the Shared Process model. 在此模型中,对于给定应用程序,节点(启动其自身包含的所有 CodePackage)上只会激活给定 ServicePackage 的一个副本。In this model, for a given application, only one copy of a given ServicePackage is activated on a node (which starts all the CodePackages contained in it). 给定 ServiceType 的所有服务的所有副本均放置在注册该 ServiceTypeCodePackage 中。All the replicas of all services of a given ServiceType are placed in the CodePackage that registers that ServiceType. 换言之,给定 ServiceType 的节点上的所有服务的所有副本共享相同的进程。In other words, all the replicas of all services on a node of a given ServiceType share the same process.

独占进程模型Exclusive Process model

Service Fabric 提供的另一个托管模型是独占进程模型。The other hosting model provided by Service Fabric is the Exclusive Process model. 在此模型中的给定节点上,每个副本驻留在其自身的专用进程中。In this model, on a given node, each replica lives in its own dedicated process. Service Fabric 激活 ServicePackage(启动其自身包含的所有 CodePackage)的一个新副本。Service Fabric activates a new copy of ServicePackage (which starts all the CodePackages contained in it). 副本放置在注册 ServiceType(副本所属服务的类型)的 CodePackage 中。Replicas are placed in the CodePackage that registered the ServiceType of the service to which the replica belongs.

如果使用 Service Fabric 5.6 或更高版本,可以在创建服务时选择独占进程模型(使用 PowerShellRESTFabricClient)。If you are using Service Fabric version 5.6 or later, you can choose the Exclusive Process model at the time you create a service (by using PowerShell, REST, or FabricClient). ServicePackageActivationMode 指定为“ExclusiveProcess”。Specify ServicePackageActivationMode as 'ExclusiveProcess'.

PS C:\>New-ServiceFabricService -ApplicationName "fabric:/App1" -ServiceName "fabric:/App1/ServiceA" -ServiceTypeName "MyServiceType" -Stateless -PartitionSchemeSingleton -InstanceCount -1 -ServicePackageActivationMode "ExclusiveProcess"
var serviceDescription = new StatelessServiceDescription
    ApplicationName = new Uri("fabric:/App1"),
    ServiceName = new Uri("fabric:/App1/ServiceA"),
    ServiceTypeName = "MyServiceType",
    PartitionSchemeDescription = new SingletonPartitionSchemeDescription(),
    InstanceCount = -1,
    ServicePackageActivationMode = ServicePackageActivationMode.ExclusiveProcess

var fabricClient = new FabricClient(clusterEndpoints);
await fabricClient.ServiceManager.CreateServiceAsync(serviceDescription);

如果应用程序清单中有一个默认服务,则可以通过指定 ServicePackageActivationMode 属性选择独占进程模型:If you have a default service in your application manifest, you can choose the Exclusive Process model by specifying the ServicePackageActivationMode attribute:

  <Service Name="MyService" ServicePackageActivationMode="ExclusiveProcess">
    <StatelessService ServiceTypeName="MyServiceType" InstanceCount="1">

现在,在应用程序 fabric:/App1 中创建另一个服务 fabric:/App1/ServiceCNow let's create another service, fabric:/App1/ServiceC, in application fabric:/App1. 该服务有 2 个分区(例如 P6P7),每个分区有 3 个副本。This service has two partitions (for example, P6 and P7), and three replicas per partition. ServicePackageActivationMode 设置为“ExclusiveProcess”。You set ServicePackageActivationMode to 'ExclusiveProcess'. 下图显示节点上的新视图:The following diagram shows new view on the node:


如此处所示,Service Fabric 激活了“MyServicePackage”的两个新副本(分别对应分区 P6P7 中的每个副本)。As you can see, Service Fabric activated two new copies of 'MyServicePackage' (one for each replica from partition P6 and P7). Service Fabric 已将每个副本放置在其 CodePackage 的专用副本中。Service Fabric placed each replica in its dedicated copy of CodePackage. 对给定应用程序使用独占进程模型时,给定 ServicePackage 可以有多个副本在节点上保持活动状态。When you use the Exclusive Process model, for a given application, multiple copies of a given ServicePackage can be active on a node. 在前面的示例中,有 3 个“MyServicePackage”副本对于 fabric:/App1 保持活动状态。In the preceding example, three copies of 'MyServicePackage' are active for fabric:/App1. “MyServicePackage”的这 3 个活跃副本均具有与自身关联的 ServicePackageActivationIdEach of these active copies of 'MyServicePackage' has a ServicePackageActivationId associated with it. 此 ID 在应用程序 fabric:/App1 中标识该副本。This ID identifies that copy within application fabric:/App1.

如果仅对应用程序使用共享进程模型,则节点上只有一个活动的 ServicePackage 副本。When you use only the Shared Process model for an application, there is only one active copy of ServicePackage on a node. ServicePackage 激活的 ServicePackageActivationId 是空字符串。The ServicePackageActivationId for this activation of ServicePackage is an empty string. 例如,fabric:/App2 就存在这种情况。This is the case, for example, with fabric:/App2.


  • 共享进程托管模型与 ServicePackageActivationMode(相当于 SharedProcess)对应。The Shared Process hosting model corresponds to ServicePackageActivationMode equals SharedProcess. 这是默认的托管模型,并且创建服务时无需指定 ServicePackageActivationModeThis is the default hosting model, and ServicePackageActivationMode need not be specified at the time of creating the service.

  • 独占进程托管模型与 ServicePackageActivationMode(相当于 ExclusiveProcess)对应。The Exclusive Process hosting model corresponds to ServicePackageActivationMode equals ExclusiveProcess. 若要使用此设置,应在创建服务时显式指定。To use this setting, you should specify it explicitly at the time of creating the service.

  • 若要查看服务的托管模型,请查询服务说明,并查看 ServicePackageActivationMode 的值。To view the hosting model of a service, query the service description, and look at the value of ServicePackageActivationMode.

使用已部署服务包Work with a deployed service package

节点上 ServicePackage 的活动副本称为已部署服务包An active copy of a ServicePackage on a node is referred to as a deployed service package. 使用独占进程模型创建服务时,对于给定应用程序,同一 ServicePackage 可能有多个已部署服务包。When you use the Exclusive Process model for creating services, for a given application, there might be multiple deployed service packages for the same ServicePackage. 执行特定于已部署服务包的操作时,应提供 ServicePackageActivationId 来标识特定的已部署服务包。If you are performing operations specific to a deployed service package, you should provide ServicePackageActivationId to identify a specific deployed service package. 例如,在报告已部署服务包的运行状况重启已部署服务包的代码包时,请提供 ID。For example, provide the ID if you are reporting the health of a deployed service package or restarting the code package of a deployed service package.

通过在节点上查询已部署服务包的列表,可以找到已部署服务包的 ServicePackageActivationId。You can find out the ServicePackageActivationId of a deployed service package by querying the list of deployed service packages on a node. 在节点上查询已部署服务包已部署副本已部署代码包时,查询结果还包含父级已部署服务包的 ServicePackageActivationId。When you are querying for the deployed service types, deployed replicas, and deployed code packages on a node, the query result also contains the ServicePackageActivationId of the parent deployed service package.


  • 在共享进程托管模型下,对于指定应用程序,指定节点上只会激活一个 ServicePackage 副本。Under the Shared Process hosting model, on a given node, for a given application, only one copy of a ServicePackage is activated. ServicePackage 的 ServicePackageActivationId 是空字符串,不需要在执行已部署服务包相关操作时指定。It has a ServicePackageActivationId equal to empty string, and need not be specified while performing operations related to the deployed service package.

  • 在独占进程托管模型下,对于指定应用程序,指定节点上可能有一个或多个活动的 ServicePackage 副本。Under the Exclusive Process hosting model, on a given node, for a given application, one or more copies of a ServicePackage can be active. 每个活动副本具有非空的 ServicePackageActivationId,需要在执行已部署服务包相关操作时指定。Each activation has a non-empty ServicePackageActivationId, specified while performing operations related to the deployed service package.

  • 如果省略了 ServicePackageActivationId,则它默认为空字符串。If ServicePackageActivationId is omitted, it defaults to empty string. 如果存在共享进程模型下激活的已部署服务包,则需在此包上执行操作。If a deployed service package that was activated under the Shared Process model is present, the operation will be performed on it. 否则,操作会失败。Otherwise, the operation fails.

  • 不要对 ServicePackageActivationId 执行一次查询或缓存。Do not query once and cache the ServicePackageActivationId. 此 ID 是动态生成的,会出于各种原因发生更改。The ID is dynamically generated, and can change for various reasons. 执行需要 ServicePackageActivationId 的操作前,应先在节点上查询已部署服务包的列表。Before performing an operation that needs ServicePackageActivationId, you should first query the list of deployed service packages on a node. 然后使用查询结果中的 ServicePackageActivationId 执行原始操作。Then use the ServicePackageActivationId from the query result to perform the original operation.

来宾可执行文件和容器应用程序Guest executable and container applications

Service Fabric 将来宾可执行文件容器应用程序视为自包含式无状态服务。Service Fabric treats guest executable and container applications as stateless services, which are self-contained. ServiceHost(进程或容器)中没有 Service Fabric 运行时。There is no Service Fabric runtime in ServiceHost (a process or container). 由于这些是自包含服务,因此每个 ServiceHost 包含的副本数不适用于这些服务。Because these services are self-contained, the number of replicas per ServiceHost is not applicable for these services. 这些服务使用的最常见配置是单分区,其中 InstanceCount 等于 -1(每个群集节点上运行一个服务代码副本)。The most common configuration used with these services is single-partition, with InstanceCount equal to -1 (one copy of the service code running on each node of the cluster).

这些服务的默认 ServicePackageActivationModeSharedProcess,在这种情况下,对于指定应用程序,Service Fabric 只会在节点上激活一个 ServicePackage 副本。The default ServicePackageActivationMode for these services is SharedProcess, in which case Service Fabric only activates one copy of ServicePackage on a node for a given application. 这意味着只有一个服务代码副本将运行节点。This means only one copy of service code will run a node. 如果希望有多个服务代码副本在节点上运行,请在创建服务时将 ServicePackageActivationMode 指定为 ExclusiveProcessIf you want multiple copies of your service code to run on a node, specify ServicePackageActivationMode as ExclusiveProcess at the time of creating the service. 例如,在创建 ServiceType(在 ServiceManifest 中指定)的多个服务多个服务(Service1ServiceN)或服务具有多个分区时,可以执行此操作。For example, you can do this when you create multiple services (Service1 to ServiceN) of ServiceType (specified in ServiceManifest), or when your service is multi-partitioned.

更改现有服务的托管模型Change the hosting model of an existing service

目前无法将现有服务的托管模型从共享进程更改为独占进程(或反之)。At the present time, you can't change the hosting model of an existing service from Shared Process to Exclusive Process (or vice-versa).

在托管模型之间进行选择Choose between the hosting models

应该评估哪种托管模型最符合自己的要求。You should evaluate which hosting model best fits your requirements. 共享进程模型更充分地利用操作系统资源,因为产生的进程较少,同一进程上的多个副本可以共享端口等。The Shared Process model uses operating system resources better, because fewer processes are spawned, and multiple replicas in the same process can share ports. 但是,如果一个副本遇到了需要关闭服务主机的错误时,会影响同一进程中的所有其他副本。However, if one of the replicas has an error where it needs to bring down the service host, it impacts all other replicas in same process.

独占进程模型将每个副本合理地分离在其自己的进程中。The Exclusive Process model provides better isolation, with every replica in its own process. 某个副本出错不会影响到其他副本。If one of the replicas has an error, it does not impact other replicas. 对于通信协议不支持端口共享的情况,此模型会很有用。This model is useful for cases where port sharing is not supported by the communication protocol. 它支持在副本级别应用资源管理。It facilitates the ability to apply resource governance at replica level. 但是,独占进程消耗的操作系统资源较多,因为它为节点上的每个副本生成一个进程。However, the Exclusive Process consumes more operating system resources, as it spawns one process for each replica on the node.

独占进程模型和应用程序模型注意事项Exclusive Process model and application model considerations

对于大多数应用程序,在 Service Fabric 中为应用程序建模时,请对每个 ServicePackage 使用同一种 ServiceTypeFor most applications, you can model your application in Service Fabric by keeping one ServiceType per ServicePackage.

在某些情况下,Service Fabric 还允许每个 ServicePackage 包含多种 ServiceType (以及一个 CodePackage 可以注册多种 ServiceType)。For certain cases, Service Fabric also allows more than one ServiceType per ServicePackage (and one CodePackage can register more than one ServiceType). 以下是这些配置适用的一些方案:The following are some of the scenarios where these configurations can be useful:

  • 希望通过生成较少进程和使用副本密度较高的进程来优化资源利用率。You want to optimize resource utilization by spawning fewer processes and having higher replica density per process.
  • 不同 ServiceType 的副本需要共享一些初始化程度高或内存成本高的常见数据。Replicas from different ServiceTypes need to share some common data that has a high initialization or memory cost.
  • 有免费的服务产品,并且想要通过将所有服务副本放置在同一进程来限制资源使用率。You have a free service offering, and you want to put a limit on resource utilization by putting all replicas of the service in same process.

独占进程托管模型不适用于每个 ServicePackage 具有多个 ServiceType 的应用程序模型。The Exclusive Process hosting model is not coherent with an application model having multiple ServiceTypes per ServicePackage. 这是因为每个 ServicePackage 具有多个 ServiceType 的目的是提高副本间的资源共享以及每个进程的副本密度。This is because multiple ServiceTypes per ServicePackage are designed to achieve higher resource sharing among replicas, and enables higher replica density per process. 独占进程模型旨在实现不同的效果。The Exclusive Process model is designed to achieve different outcomes.

请考虑这种情况:每个 ServicePackage 有多个 ServiceType,并且不同的 CodePackage 分别注册一个 ServiceType.Consider the case of multiple ServiceTypes per ServicePackage, with a different CodePackage registering each ServiceType. 假设有一个具有 2 个 CodePackage 的 ServicePackage“MultiTypeServicePackage” :Let's say we have a ServicePackage 'MultiTypeServicePackage', which has two CodePackages:

  • “MyCodePackageA”注册 ServiceType“MyServiceTypeA”。'MyCodePackageA', which registers ServiceType 'MyServiceTypeA'.
  • “MyCodePackageB”注册 ServiceType“MyServiceTypeB”。'MyCodePackageB', which registers ServiceType 'MyServiceTypeB'.

现在,我们创建应用程序 fabric:/SpecialAppNow, let's say that we create an application, fabric:/SpecialApp. fabric:/SpecialApp 中,使用独占进程模型创建以下 2 个服务:Inside fabric:/SpecialApp, we create following two services with the Exclusive Process model:

  • “MyServiceTypeA”类型的服务 fabric:/SpecialApp/ServiceA 有 2 个分区(例如 P1P2),每个分区有 3 个副本。Service fabric:/SpecialApp/ServiceA of type 'MyServiceTypeA', with two partitions (for example, P1 and P2), and three replicas per partition.
  • “MyServiceTypeB”类型的服务 fabric:/SpecialApp/ServiceB 有 2 个分区(P3P4),每个分区有 3 个副本。Service fabric:/SpecialApp/ServiceB of type 'MyServiceTypeB', with two partitions (P3 and P4), and three replicas per partition.

在给定节点上,两个服务将分别有两个副本。On a given node, both of the services have two replicas each. 由于使用独占进程模型创建了服务,Service Fabric 将为每个复本激活一个新“MyServicePackage”副本。Because we used the Exclusive Process model to create the services, Service Fabric activates a new copy of 'MyServicePackage' for each replica. 每次激活“MultiTypeServicePackage”将启动“MyCodePackageA”和“MyCodePackageB”的一个副本。Each activation of 'MultiTypeServicePackage' starts a copy of 'MyCodePackageA' and 'MyCodePackageB'. 但是,“MyCodePackageA”或“MyCodePackageB”中只有一个将托管副本(为此副本激活了“MultiTypeServicePackage”)。However, only one of 'MyCodePackageA' or 'MyCodePackageB' hosts the replica for which 'MultiTypeServicePackage' was activated. 下图显示了节点视图:The following diagram shows the node view:


为服务 fabric:/SpecialApp/ServiceAP1 分区的副本激活“MultiTypeServicePackage”时,“MyCodePackageA”将托管该副本。In the activation of 'MultiTypeServicePackage' for the replica of partition P1 of service fabric:/SpecialApp/ServiceA, 'MyCodePackageA' is hosting the replica. “MyCodePackageB”正在运行。'MyCodePackageB' is running. 类似地,为服务 fabric:/SpecialApp/ServiceBP3 分区的副本激活“MultiTypeServicePackage”时,“MyCodePackageB”将托管该副本。Similarly, in the activation of 'MultiTypeServicePackage' for the replica of partition P3 of service fabric:/SpecialApp/ServiceB, 'MyCodePackageB' is hosting the replica. “MyCodePackageA”正在运行。'MyCodePackageA' is running. 因此,每个 ServicePackageCodePackage(注册不同的 ServiceType)数量越多,冗余资源使用率就越高。Hence, the greater the number of CodePackages (registering different ServiceTypes) per ServicePackage, the higher the redundant resource usage.

但是,如果使用共享进程模型创建服务 fabric:/SpecialApp/ServiceAfabric:/SpecialApp/ServiceB,Service Fabric 将只为应用程序 fabric:/SpecialApp 激活一个“MultiTypeServicePackage”副本。However, if we create the services fabric:/SpecialApp/ServiceA and fabric:/SpecialApp/ServiceB with the Shared Process model, Service Fabric activates only one copy of 'MultiTypeServicePackage' for the application fabric:/SpecialApp. “MyCodePackageA”托管服务 fabric:/SpecialApp/ServiceA 的所有副本。'MyCodePackageA' hosts all replicas for the service fabric:/SpecialApp/ServiceA. “MyCodePackageB”托管服务 fabric:/SpecialApp/ServiceB 的所有副本。'MyCodePackageB' hosts all replicas for the service fabric:/SpecialApp/ServiceB. 下图显示了此设置中的节点视图:The following diagram shows the node view in this setting:


在上面的示例中,你可能会想,如果“MyCodePackageA”同时注册“MyServiceTypeA”和“MyServiceTypeB”并且没有“MyCodePackageB”,那么将不会运行冗余的 CodePackageIn the preceding example, you might think that if 'MyCodePackageA' registers both 'MyServiceTypeA' and 'MyServiceTypeB', and there is no 'MyCodePackageB', then there is no redundant CodePackage running. 这是对的,但此应用程序模型不适用于独占进程托管模型。Although this is correct, this application model does not align with the Exclusive Process hosting model. 如果目的是将每个副本放入其自己的专用进程,则不需要从同一个 CodePackage 注册两个 ServiceTypeIf the goal is to put each replica in its own dedicated process, you do not need to register both ServiceTypes from same CodePackage. 只需将每个 ServiceType 放入其自身的 ServicePackage 即可。Instead, you simply put each ServiceType in its own ServicePackage.

Reliable Services 和执行组件分支子进程Reliable Services and Actor forking subprocesses

服务结构不支持 Reliable Services,因此也不支持 Reliable Actors 分支子进程。Service Fabric doesn't support reliable services and subsequently reliable actors forking subprocesses. 这里举例说明其不受支持的原因:CodePackageActivationContext 不能用于注册不受支持的子过程,并且取消令牌仅发送到已注册过程;若子过程在父过程收到取消令牌后未关闭,会导致各种问题,例如升级失败。An example of why its not supported is CodePackageActivationContext can not be used to register an unsupported subprocess, and cancellation tokens are only sent to registered processes; resulting in all sorts of issues, such as upgrade failures, when subprocesses don't close after the parent process has received a cancellation token.

后续步骤Next steps

打包应用程序并准备好进行部署。Package an application and get it ready to deploy.

部署和删除应用程序Deploy and remove applications. 此文介绍如何使用 PowerShell 来管理应用程序实例。This article describes how to use PowerShell to manage application instances.