打包现有可执行文件并将其部署到 Service Fabric

将现有可执行文件打包为来宾可执行文件时,可以选择是使用 Visual Studio 项目模板,还是手动创建应用程序包。 使用 Visual Studio 时,新的项目模板为用户创建应用程序包结构和清单文件。

提示

将现有 Windows 可执行文件打包到服务中的最简单方法就是使用 Visual Studio 以及在 Linux 上使用 Yeoman

使用 Visual Studio 打包和部署现有可执行文件

Visual Studio 提供 Service Fabric 服务模板将来宾可执行文件部署到 Service Fabric 群集。

  1. 依次选择“文件”“新建项目”,并创建一个 Service Fabric 应用程序。
  2. 选择“来宾可执行文件”作为服务模板。
  3. 单击“浏览” 选择包含所需可执行文件的文件夹,并填充余下的参数来创建服务。
    • 代码包行为。 可以设置为将文件夹中的所有内容复制到 Visual Studio 项目,如果可执行文件不会更改,则这种设置会很有用。 如果预期可执行文件会更改,并且希望能够动态选择新版本,则可以改为选择文件夹的链接。 在 Visual Studio 中创建应用程序项目时,可以使用链接的文件夹。 这会从项目内部链接到源位置,从而能够在来宾可执行文件的源目标中对它进行更新。 这些更新会在生成时成为应用程序包的一部分。
    • Program 指定为了启动服务而应该运行的可执行文件。
    • Arguments 指定应传递给可执行文件的参数。 它可以是带有实参的形参的列表。
    • WorkingFolder 指定要启动的进程的工作目录。 可以指定三个值:
      • CodeBase 指定将应用程序包中的 Code 目录(如上述文件结构中的 Code 目录所示)设为工作目录。
      • CodePackage 指定将应用程序包的根目录(如上述文件结构中的 GuestService1Pkg 目录所示)设为工作目录。
      • Work 指定将文件放置在 Work 子目录中。
  4. 为服务命名,并单击“确定” 。
  5. 如果服务需要使用终结点进行通信,现在可以在 ServiceManifest.xml 文件中添加协议、端口和类型。 例如: <Endpoint Name="NodeAppTypeEndpoint" Protocol="http" Port="3000" UriScheme="http" PathSuffix="myapp/" Type="Input" />
  6. 接下来,可以通过在 Visual Studio 中调试解决方案,针对本地群集使用打包和发布操作。 准备就绪后,可将应用程序发布到远程群集,或者将解决方案签入源代码管理。
  7. 请阅读检查正在运行的应用程序,了解如何查看在 Service Fabric Explorer 中运行的来宾可执行服务。

有关示例演练,请参阅使用 Visual Studio 创建第一个来宾可执行应用程序

使用 Visual Studio 打包多个可执行文件

可使用 Visual Studio 生成包含多个来宾可执行文件的应用程序包。 在添加第一个来宾可执行文件后,右键单击应用程序项目并选择“添加”-“新建 Service Fabric 服务”,以将第二个来宾可执行文件项目添加到解决方案。

注意

如果选择在 Visual Studio 项目中链接源,则生成 Visual Studio 解决方案可确保应用程序包能够与源中的更改保持同步。

使用 Yeoman 在 Linux 上打包和部署现有可执行文件

用于在 Linux 上创建和部署来宾可执行文件的过程与部署 C# 或 Java 应用程序相同。

  1. 在终端中,键入 yo azuresfguest
  2. 为应用程序命名。
  3. 命名服务,并提供详细信息,包括可执行文件的路径以及调用该服务所必须使用的参数。

Yeoman 创建应用程序包,其中包含相应的应用程序和清单文件,以及安装和卸载脚本。

使用 Linux 上的 Yeoman 打包多个可执行文件

要将另一个服务添加到使用 yo 创建的应用程序,请执行以下步骤:

  1. 将目录更改为现有应用程序的根目录。 例如 cd ~/YeomanSamples/MyApplication(如果 MyApplication 是 Yeoman 创建的应用程序)。
  2. 运行 yo azuresfguest:AddService 并提供必要的详细信息。

手动打包和部署现有的可执行文件

手动打包来宾可执行文件的过程基于以下常规步骤:

  1. 创建包目录结构。
  2. 添加应用程序的代码和配置文件。
  3. 编辑服务清单文件。
  4. 编辑应用程序清单文件。

创建包目录结构

可以首先创建目录结构,如打包 Azure Service Fabric 应用中所述。

添加应用程序的代码和配置文件

创建了目录结构之后,可以在 code 和 config 目录下添加应用程序的代码和配置文件。 还可以在 code 或 config 目录下创建其他目录或子目录。

Service Fabric 对应用程序根目录下的内容执行了 xcopy,因此除创建 code 和 settings 这两个顶级目录以外没有其他任何预定义结构可以使用。 (如果需要,可以选择不同的名称。下一部分中会提供更多详细信息。)

注意

确保包含应用程序需要的所有文件和依赖项。 Service Fabric 将复制群集中所有节点上的应用程序包的内容,会在群集中部署应用程序的服务。 包中应该包含应用程序需要运行的所有代码。 不要假定已安装依赖项。

编辑服务清单文件

下一步是编辑服务清单文件以包含如下信息:

  • 服务类型的名称。 这是 Service Fabric 用于标识服务的 ID。
  • 用于启动应用程序的命令 (ExeHost)。
  • 为设置应用程序而需要运行的任何脚本 (SetupEntrypoint)。

下面是 ServiceManifest.xml 文件的示例:

<?xml version="1.0" encoding="utf-8"?>
<ServiceManifest xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" Name="NodeApp" Version="1.0.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric">
   <ServiceTypes>
      <StatelessServiceType ServiceTypeName="NodeApp" UseImplicitHost="true"/>
   </ServiceTypes>
   <CodePackage Name="code" Version="1.0.0.0">
      <SetupEntryPoint>
         <ExeHost>
             <Program>scripts\launchConfig.cmd</Program>
         </ExeHost>
      </SetupEntryPoint>
      <EntryPoint>
         <ExeHost>
            <Program>node.exe</Program>
            <Arguments>bin/www</Arguments>
            <WorkingFolder>CodePackage</WorkingFolder>
         </ExeHost>
      </EntryPoint>
   </CodePackage>
   <Resources>
      <Endpoints>
         <Endpoint Name="NodeAppTypeEndpoint" Protocol="http" Port="3000" Type="Input" />
      </Endpoints>
   </Resources>
</ServiceManifest>

以下部分介绍了需要更新的文件的不同部分。

更新 ServiceTypes

<ServiceTypes>
  <StatelessServiceType ServiceTypeName="NodeApp" UseImplicitHost="true" />
</ServiceTypes>
  • 可为 ServiceTypeName选择所需的任何名称。 该值在 ApplicationManifest.xml 文件中用于标识服务。
  • 指定 UseImplicitHost="true"。 此属性告知 Service Fabric 服务基于自包含的应用,因此 Service Fabric 只需要将其作为进程启动并监视其运行状况。

更新 CodePackage

CodePackage 元素指定服务代码的位置(和版本)。

<CodePackage Name="Code" Version="1.0.0.0">

Name 元素用于在包含服务代码的应用程序包中指定目录的名称。 CodePackage 也有 version 属性。 这不仅可用于指定代码的版本,还可用于升级服务的代码,具体方法为在 Service Fabric 中使用应用程序生命周期管理基础结构。

可选:更新 SetupEntrypoint

<SetupEntryPoint>
   <ExeHost>
       <Program>scripts\launchConfig.cmd</Program>
   </ExeHost>
</SetupEntryPoint>

SetupEntryPoint 元素用于指定在启动服务代码之前应执行的任何可执行文件或批处理文件。 这是一个可选步骤,因此在不需要初始化时无需包含在内。 每次重新启动服务时,会执行 SetupEntryPoint。

只有一个 SetupEntryPoint,因此如果应用程序的设置需要多个脚本,则设置脚本需要组合在单个批处理文件中。 SetupEntryPoint 可以执行任何类型的文件 - 可执行文件、批处理文件和 PowerShell cmdlet。 有关详细信息,请参阅配置 SetupEntryPoint

在上面的示例中,SetupEntryPoint 会运行位于 code 目录的 scripts 子目录中的 LaunchConfig.cmd 批处理文件(假定 WorkingFolder 元素设置为 CodeBase)。

更新 EntryPoint

<EntryPoint>
  <ExeHost>
    <Program>node.exe</Program>
    <Arguments>bin/www</Arguments>
    <WorkingFolder>CodeBase</WorkingFolder>
  </ExeHost>
</EntryPoint>

服务清单文件中的 EntryPoint 元素用于指定如何启动该服务。

ExeHost 元素指定应用于启动该服务的可执行文件(和参数)。 可以选择将 IsExternalExecutable="true" 属性添加到 ExeHost,以指示该程序是代码包外部的外部可执行文件。 例如,<ExeHost IsExternalExecutable="true">

  • Program 指定应启动服务的可执行文件的名称。
  • Arguments 指定应传递给可执行文件的参数。 它可以是带有实参的形参的列表。
  • WorkingFolder 指定要启动的进程的工作目录。 可以指定三个值:
    • CodeBase 指定工作目录将设置为应用程序包中的 code 目录(前述文件结构中的 Code 目录)。
    • CodePackage 指定将应用程序包的根目录(如上述文件结构中的 GuestService1Pkg 所示)设为工作目录。
      • Work 指定将文件放置在 Work 子目录中。

WorkingFolder 用于设置正确的工作目录,以便应用程序或初始化脚本可以使用相对路径。

更新终结点并在命名服务中注册以进行通信

<Endpoints>
   <Endpoint Name="NodeAppTypeEndpoint" Protocol="http" Port="3000" Type="Input" />
</Endpoints>

在前面的示例中, Endpoint 元素指定应用程序可以侦听的终结点。 在此示例中,Node.js 应用程序侦听端口 3000 上的 http 流量。

此外,可以要求 Service Fabric 将此终结点发布到命名服务,使其他服务可以发现此服务的终结点地址。 然后,便可以在服务(来宾可执行文件)之间进行通信。 已发布的终结点地址格式为 UriScheme://IPAddressOrFQDN:Port/PathSuffixUriSchemePathSuffix 是可选属性。 IPAddressOrFQDN 是此可执行文件所在节点的 IP 地址或完全限定的域名,系统会为你计算此参数。

在以下示例中,部署服务后,Service Fabric Explorer 中会显示针对服务实例发布的终结点(类似于 http://10.1.4.92:3000/myapp/ )。 如果这是本地计算机,则显示 http://localhost:3000/myapp/

<Endpoints>
   <Endpoint Name="NodeAppTypeEndpoint" Protocol="http" Port="3000"  UriScheme="http" PathSuffix="myapp/" Type="Input" />
</Endpoints>

可以将这些地址与反向代理结合使用,在服务之间进行通信。

编辑应用程序清单文件

配置 Servicemanifest.xml 文件之后,需要对 ApplicationManifest.xml 文件进行一些更改,确保使用正确的服务类型和名称。

<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" ApplicationTypeName="NodeAppType" ApplicationTypeVersion="1.0" xmlns="http://schemas.microsoft.com/2011/01/fabric">
   <ServiceManifestImport>
      <ServiceManifestRef ServiceManifestName="NodeApp" ServiceManifestVersion="1.0.0.0" />
   </ServiceManifestImport>
</ApplicationManifest>

ServiceManifestImport

ServiceManifestImport 元素中,可以指定要包含在应用中的一个或多个服务。 ServiceManifestName 指定 ServiceManifest.xml 文件所在的目录名称,用来参考服务。

<ServiceManifestImport>
  <ServiceManifestRef ServiceManifestName="NodeApp" ServiceManifestVersion="1.0.0.0" />
</ServiceManifestImport>

设置日志记录

对于来宾可执行文件,最好能够查看控制台日志,以查明应用程序和配置脚本是否显示了任何错误。 可以使用 ConsoleRedirection 元素在 ServiceManifest.xml 文件中配置控制台重定向。

警告

永远不要在生产中部署的应用程序中使用控制台重定向策略,因为这可能会影响应用程序故障转移。 将其用于本地开发和调试目的。

<EntryPoint>
  <ExeHost>
    <Program>node.exe</Program>
    <Arguments>bin/www</Arguments>
    <WorkingFolder>CodeBase</WorkingFolder>
    <ConsoleRedirection FileRetentionCount="5" FileMaxSizeInKb="2048"/>
  </ExeHost>
</EntryPoint>

ConsoleRedirection 可用于将控制台输出(stdout 和 stderr)重定向到工作目录。 这可验证在 Service Fabric 群集中设置或执行应用程序时没有出现错误。

FileRetentionCount 确定保存在工作目录中的文件的数量。 例如,值 5 表示前 5 个执行的日志文件存储在工作目录中。

FileMaxSizeInKb 指定日志文件的最大大小。

日志文件保存在服务的一个工作目录中。 若要确定文件所在的位置,请使用 Service Fabric Explorer 来确定运行服务的节点以及所使用的工作目录。 本文中后面部分介绍了此过程。

部署

最后一步是部署应用程序。 下面的 PowerShell 脚本展示了如何将应用程序部署到本地开发群集,并启动新的 Service Fabric 服务。


Connect-ServiceFabricCluster localhost:19000

Write-Host 'Copying application package...'
Copy-ServiceFabricApplicationPackage -ApplicationPackagePath 'C:\Dev\MultipleApplications' -ImageStoreConnectionString 'file:C:\SfDevCluster\Data\ImageStoreShare' -ApplicationPackagePathInImageStore 'nodeapp'

Write-Host 'Registering application type...'
Register-ServiceFabricApplicationType -ApplicationPathInImageStore 'nodeapp'

New-ServiceFabricApplication -ApplicationName 'fabric:/nodeapp' -ApplicationTypeName 'NodeAppType' -ApplicationTypeVersion 1.0

New-ServiceFabricService -ApplicationName 'fabric:/nodeapp' -ServiceName 'fabric:/nodeapp/nodeappservice' -ServiceTypeName 'NodeApp' -Stateless -PartitionSchemeSingleton -InstanceCount 1

提示

如果包较大或包含多个文件,请先压缩包,并将其复制到映像存储区。 在此处了解详细信息。

Service Fabric 服务可以采用各种“配置”进行部署。例如,可将其作为一个或多个实例部署,或者,可以采用在 Service Fabric 群集的每个节点上都有该服务的一个实例的方式来部署。

New-ServiceFabricService cmdlet 的 InstanceCount 参数用于指定应在 Service Fabric 群集中启动的服务实例的数量。 可以根据要部署的应用程序类型设置 InstanceCount 值。 最常见的两种方案是:

  • InstanceCount = "1"。 在此情况下,只会在群集中部署一个服务实例。 Service Fabric 的计划程序确定在哪一个节点上部署服务。
  • InstanceCount ="-1"。 在此情况下,会在 Service Fabric 群集中的每个节点上部署一个服务实例。 结果是群集中的每个节点上都有一个(且只有一个)服务实例。

这是前端应用程序(不包括 REST 终结点)的有用配置,因为客户端应用程序需要“连接到”群集中的任何节点才能使用该终结点。 例如,当 Service Fabric 群集的所有节点都连接到负载均衡器时,也可以使用此配置。 然后,客户端流量可以分布于在集群中所有节点上运行的服务。

检查正在运行的应用程序

在 Service Fabric Explorer 中,确定服务在其中运行的节点。 在此示例中,它在节点 1 上运行:

Node where service is running

导航到该节点并浏览到应用程序后,会看到基本节点信息(包括在它磁盘上的位置)。

Location on disk

如果使用服务器资源管理器浏览目录,可以找到工作目录和服务的日志文件夹,如以下屏幕截图所示:

Location of log

后续步骤

在本文中,我们了解了如何打包来宾可执行文件并将其部署到 Service Fabric。 有关相关信息和任务,请参阅以下文章。