Initializer Code Packages

Начиная с версии 7.1, Service Fabric поддерживает Initializer CodePackages для контейнеров и гостевых исполняемых приложений. Функция Initializer CodePackages дает возможность выполнить инициализацию в области действия ServicePackage до начала выполнения других CodePackages. Это аналог SetupEntryPoint является для CodePackage, но по отношению к ServicePackage.

Прежде чем продолжить чтение этой статьи, рекомендуется ознакомиться с моделью приложения Service Fabric и моделью размещения Service Fabric.

Примечание

Initializer CodePackages в настоящее время не поддерживают службы, надписанные с использованием модели программирования Reliable Services.

Семантика

Ожидается, что выполнение Initializer CodePackage завершится успешно (код выхода 0) . В случае сбоя Initializer CodePackage перезапускается повторно до успешного завершения. Разрешено использование нескольких Initializer CodePackage. Они запускаются до успешного завершения, последовательно, в указанном порядке и до начала выполнения других CodePackages в ServicePackage.

Указание Initializer CodePackages

CodePackage можно пометить как инициализатор, указав атрибуту Initializer значение true в ServiceManifest. При наличии нескольких Initializer CodePackage, порядок их выполнения можно указать в атрибуте ExecOrder. ExecOrder должен быть целым неотрицательным числом, этот параметр действует только для Initializer CodePackage. В первую очередь выполняется Initializer CodePackage с более низким значением ExecOrder. Если для Initializer CodePackage не указан ExecOrder, то принимается значение по умолчанию равное 0. Относительный порядок выполнения Initializer CodePackage с одинаковым значением ExecOrder не определен.

В следующем фрагменте ServiceManifest описаны три CodePackage, два из которых помечены как инициализаторы. При активации этого ServicePackage пакет InitCodePackage0 выполняется в первую очередь: у него самое низкое значение ExecOrder. При успешном завершении (код выхода 0) пакета InitCodePackage0, выполняется пакет InitCodePackage1. Наконец, при успешном завершении InitCodePackage1, выполняется WorkloadCodePackage.

<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>

Полный пример использования CodePackages

Давайте рассмотрим полный пример использования Initializer CodePackages.

Важно!

В следующем примере предполагается, что вы знакомы с приложениями–контейнерами Windows, которые используют Service Fabric и Docker.

Этот пример обращается к mcr.microsoft.com/windows/nanoserver:1809. Контейнеры Windows Server совместимы не со всеми версиями ОС узла. Дополнительные сведения см. в разделе Совместимость версий контейнеров Windows.

Следующий манифест ServiceManifest.xml построен на основе фрагмента ServiceManifest, описанного выше. InitCodePackage0, InitCodePackage1 и WorkloadCodePackage — это CodePackages, которые представляют контейнеры. После активации первым выполняется InitCodePackage0. Он записывает сообщение в журнал и завершает работу. Затем, выполняется InitCodePackage1, который также записывает сообщение в журнал и завершает работу. Наконец, начинается выполнение WorkloadCodePackage. Он также записывает сообщение в файл, выводит содержимое файла в stdout, а затем постоянно выполняет проверку подключения.

<?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, приведенном выше. Обратите внимание, что там задает одно и то же подключение Том для всех контейнеров, т. е. C:\WorkspaceOnHost подключается к C:\WorkspaceOnContainer на всех трех контейнерах. В итоге контейнеры ведут запись в один и тот же журнал в порядке их активации.

<?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 должно быть следующее содержимое.

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

Дальнейшие действия

Дополнительные сведения приведены в статьях ниже.