Initializer CodePackageInitializer CodePackages

从 7.1 版开始,Service Fabric 支持适用于容器应用程序和来宾可执行文件应用程序的 Initializer CodePackageStarting with version 7.1, Service Fabric supports Initializer CodePackages for containers and guest executable applications. Initializer CodePackage 提供了在其他 Codepackage 开始执行之前在 ServicePackage 范围内执行初始化操作的机会。Initializer CodePackages provide the opportunity to perform initializations at the ServicePackage scope before other CodePackages begin execution. 它们与 ServicePackage 的关系类似于 SetupEntryPoint 相对于 CodePackage 的关系。Their relationship to a ServicePackage is analogous to what a SetupEntryPoint is for a CodePackage.

继续阅读本文之前,建议先熟悉 Service Fabric 应用程序模型Service Fabric 托管模型Before proceeding with this article, we recommend getting familiar with the Service Fabric application model and the Service Fabric hosting model.

备注

使用 Reliable Services 编程模型编写的服务目前不支持 Initializer CodePackage。Initializer CodePackages are currently not supported for services written using the Reliable Services programming model.

语义Semantics

正常情况下,Initializer CodePackage 在运行后会成功完成(退出代码为 0)。An Initializer CodePackage is expected to run to successful completion (exit code 0). 失败的 Initializer CodePackage 会重启,直至成功完成。A failed Initializer CodePackage is restarted until it successfully completes. 在 ServicePackage 中的其他 CodePackage 开始执行之前,允许多个 Initializer CodePackage 顺序执行(按指定的顺序),直至成功完成。 Multiple Initializer CodePackages are allowed and are executed to successful completion, sequentially, in a specified order before other CodePackages in the ServicePackage begin execution.

指定 Initializer CodePackageSpecifying Initializer CodePackages

可以将 CodePackage 标记为 Initializer,方法是在 ServiceManifest 中将 Initializer 属性设置为 trueYou can mark a CodePackage as an Initializer by setting the Initializer attribute to true in the ServiceManifest. 如果有多个 Initializer CodePackage,则可通过 ExecOrder 属性指定其执行顺序。When there are multiple Initializer CodePackages, their order of execution can be specified via the ExecOrder attribute. ExecOrder 必须为非负整数,仅对 Initializer CodePackage 有效。ExecOrder must be a non-negative integer and is only valid for Initializer CodePackages. ExecOrder 值较小的 Initializer CodePackage 先执行。Initializer CodePackages with lower values of ExecOrder are executed first. 如果没有为 Initializer CodePackage 指定 ExecOrder,则会采用默认值 0。If ExecOrder is not specified for an Initializer CodePackage, a default value of 0 is assumed. 未指定 ExecOrder 值相同的 Initializer CodePackage 的相对执行顺序。Relative execution order of Initializer CodePackages with the same value of ExecOrder is unspecified.

以下 ServiceManifest 代码片段描述了三个 CodePackage,其中的两个标记为 Initializer。The following ServiceManifest snippet describes three CodePackages two of which are marked as Initializers. 激活此 ServicePackage 时,InitCodePackage0 先执行,因为它的 ExecOrder 值最小。When this ServicePackage is activated, InitCodePackage0 is executed first since it has the lowest value of ExecOrder. InitCodePackage0 成功完成(退出代码为 0)后,系统会执行 InitCodePackage1。On successful completion (exit code 0) of InitCodePackage0, InitCodePackage1 is executed. 最后,在成功完成 InitCodePackage1 后,会执行 WorkloadCodePackage。Finally, on successful completion of InitCodePackage1, WorkloadCodePackage is executed.

<CodePackage Name="InitCodePackage0" Version="1.0" Initializer="true" ExecOrder="0">
  ...
</CodePackage>

<CodePackage Name="InitCodePackage1" Version="1.0" Initializer="true" ExecOrder="1">
  ...
</CodePackage>

<CodePackage Name="WorkloadCodePackage" Version="1.0">
  ...
</CodePackage>

使用 Initializer CodePackage 的完整示例Complete example using Initializer CodePackages

让我们看看一个使用 Initializer CodePackage 的完整示例。Let's look at a complete example using Initializer CodePackages.

重要

以下示例假定你熟悉如何创建使用 Service Fabric 和 Docker 的 Windows 容器应用程序The following example assumes familiarity with creating Windows container applications using Service Fabric and Docker.

此示例引用了 mcr.microsoft.com/windows/nanoserver:1809。This example references mcr.microsoft.com/windows/nanoserver:1809. Windows Server 容器并非在所有主机 OS 版本间都兼容。Windows Server containers are not compatible across all versions of a host OS. 若要了解详细信息,请参阅 Windows 容器版本兼容性To learn more, see Windows Container Version Compatibility.

以下 ServiceManifest.xml 在前述 ServiceManifest 代码片段基础上构建。The following ServiceManifest.xml builds upon the ServiceManifest snippet described earlier. InitCodePackage0、InitCodePackage1 和 WorkloadCodePackage 是表示容器的 CodePackage 。InitCodePackage0, InitCodePackage1 and WorkloadCodePackage are CodePackages which represent containers. 激活后,InitCodePackage0 先执行。Upon activation, InitCodePackage0 is executed first. 它将一条消息记录到一个文件中,然后退出。It logs a message to a file and exits. 接下来执行 InitCodePackage1,它也将一条消息记录到一个文件中,然后退出。Next, InitCodePackage1 is executed which also logs a message to a file and exits. 最后,WorkloadCodePackage 开始执行。Finally, the WorkloadCodePackage begins execution. 它也将一条消息记录到一个文件中,将文件内容输出到 stdout,然后一直 ping 下去。It also logs a message to a file, outputs the contents of the file to stdout and then pings forever.

<?xml version="1.0" encoding="UTF-8"?>
<ServiceManifest Name="WindowsInitCodePackageServicePackage" Version="1.0" xmlns="http://schemas.microsoft.com/2011/01/fabric" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Description>Windows Init CodePackage Service</Description>
  <ServiceTypes>
    <StatelessServiceType ServiceTypeName="WindowsInitCodePackageServiceType"  UseImplicitHost="true"/>
  </ServiceTypes>
  <CodePackage Name="InitCodePackage0" Version="1.0" Initializer="true" ExecOrder="0">
    <EntryPoint>
      <ContainerHost>
        <ImageName>mcr.microsoft.com/windows/nanoserver:1809</ImageName>
        <Commands>/c,echo Hi from InitCodePackage0. &gt; C:\WorkspaceOnContainer\log.txt</Commands>
        <EntryPoint>cmd</EntryPoint>
      </ContainerHost>
    </EntryPoint>
  </CodePackage>

  <CodePackage Name="InitCodePackage1" Version="1.0" Initializer="true" ExecOrder="1">
    <EntryPoint>
      <ContainerHost>
        <ImageName>mcr.microsoft.com/windows/nanoserver:1809</ImageName>
        <Commands>/c,echo Hi from InitCodePackage1. &gt;&gt; C:\WorkspaceOnContainer\log.txt</Commands>
        <EntryPoint>cmd</EntryPoint>
      </ContainerHost>
    </EntryPoint>
  </CodePackage>

  <CodePackage Name="WorkloadCodePackage" Version="1.0">
    <EntryPoint>
      <ContainerHost>
        <ImageName>mcr.microsoft.com/windows/nanoserver:1809</ImageName>
        <Commands>/c,echo Hi from WorkloadCodePackage. &gt;&gt; C:\WorkspaceOnContainer\log.txt &amp;&amp; type C:\WorkspaceOnContainer\log.txt &amp;&amp; ping -t 127.0.0.1 &gt; nul</Commands>
        <EntryPoint>cmd</EntryPoint>
      </ContainerHost>
    </EntryPoint>
  </CodePackage>
</ServiceManifest>

以下 ApplicationManifest.xml 描述了一个基于上述 ServiceManifest.xml 的应用程序。The following ApplicationManifest.xml describes an application based on the ServiceManifest.xml discussed above. 请注意,它为所有容器指定同一个卷装载。也就是说,在所有三个容器中,C:\WorkspaceOnHost 都装载在 C:\WorkspaceOnContainer 中。Note that it specifies the same Volume mount for all the containers, i.e. C:\WorkspaceOnHost is mounted at C:\WorkspaceOnContainer on all three containers. 最终效果是,所有容器都按其激活顺序将内容写入同一日志文件。The net effect is that all the containers write to the same log file in the order in which they are activated.

<?xml version="1.0" encoding="UTF-8"?>
<ApplicationManifest ApplicationTypeName="WindowsInitCodePackageApplicationType" ApplicationTypeVersion="1.0" xmlns="http://schemas.microsoft.com/2011/01/fabric" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

  <Description>Windows Init CodePackage Application</Description>

  <ServiceManifestImport>
    <ServiceManifestRef ServiceManifestName="WindowsInitCodePackageServicePackage" ServiceManifestVersion="1.0"/>
    <Policies>
      <ContainerHostPolicies CodePackageRef="InitCodePackage0" ContainersRetentionCount="2" RunInteractive="true">
        <Volume Source="C:\WorkspaceOnHost" Destination="C:\WorkspaceOnContainer" IsReadOnly="false" />
      </ContainerHostPolicies>

     <ContainerHostPolicies CodePackageRef="InitCodePackage1" ContainersRetentionCount="2" RunInteractive="true">
        <Volume Source="C:\WorkspaceOnHost" Destination="C:\WorkspaceOnContainer" IsReadOnly="false" />
      </ContainerHostPolicies>

      <ContainerHostPolicies CodePackageRef="WorkloadCodePackage" ContainersRetentionCount="2" RunInteractive="true">
        <Volume Source="C:\WorkspaceOnHost" Destination="C:\WorkspaceOnContainer" IsReadOnly="false" />
      </ContainerHostPolicies>
    </Policies>
  </ServiceManifestImport>

  <DefaultServices>
    <Service Name="WindowsInitCodePackageService" ServicePackageActivationMode="ExclusiveProcess">
      <StatelessService ServiceTypeName="WindowsInitCodePackageServiceType" InstanceCount="1">
        <SingletonPartition />
      </StatelessService>
    </Service>
  </DefaultServices>
</ApplicationManifest>

成功激活 ServicePackage 后,C:\WorkspaceOnHost\log.txt 的内容应如下所示。Once the ServicePackage has been successfully activated, the contents of C:\WorkspaceOnHost\log.txt should be the following.

C:\Users\test>type C:\WorkspaceOnHost\log.txt
Hi from InitCodePackage0.
Hi from InitCodePackage1.
Hi from WorkloadCodePackage.

后续步骤Next steps

请参阅以下文章,了解相关信息。See the following articles for related information.