如何通过Azure DevOps用单制品部署多名称Service Fabric服务实例
我之前折腾过几乎一模一样的场景,完全明白你想通过单制品+Azure DevOps多阶段发布流水线,在同一个Service Fabric集群里部署不同命名服务实例(比如DEV_MyService、QA_MyService)的需求。之前参数化失败大概率是没找对Service Fabric配置参数化的正确姿势,下面是亲测有效的实现步骤:
第一步:给Service Fabric应用的服务名称做参数化配置
首先要修改你的Service Fabric应用的ApplicationManifest.xml,把硬编码的服务名称替换成可配置的参数:
- 在
<Parameters>节点下添加自定义参数,比如:
<Parameters> <Parameter Name="MyServiceInstanceName" DefaultValue="MyService" /> </Parameters>
- 找到对应的
<ServiceManifestImport>节点,把原来的<ServiceName>值改成参数引用:
<ServiceManifestImport> <ServiceManifestRef ServiceManifestName="MyServicePkg" ServiceManifestVersion="1.0.0" /> <ServiceName>[MyServiceInstanceName]</ServiceName> </ServiceManifestImport>
如果你的应用名称也需要和服务名称对应(避免不同实例的应用名称冲突),也可以把应用名称参数化:
<ApplicationName>[MyAppInstanceName]</ApplicationName>
然后在Parameters里添加MyAppInstanceName的默认值,比如DefaultValue="MyServiceApp"。
第二步:保持构建流水线不变,输出通用制品
这一步很省心,你不需要修改现有的构建流水线——因为我们已经把可变部分移到了配置参数里,构建出来的应用包是完全通用的,不需要为不同环境做任何定制。只要确保构建后的制品包含修改后的ApplicationManifest.xml就行。
第三步:在Azure DevOps发布流水线里配置多阶段参数
接下来就是在发布流水线里给每个环境(DEV、QA等)设置专属变量,让部署任务自动替换参数:
给每个发布阶段配置专属变量:
- 进入发布流水线的某个阶段(比如DEV阶段),打开「变量」选项卡,添加变量
ServiceInstanceName,值设为DEV_MyService;如果参数化了应用名称,再添加AppInstanceName,值设为DEV_MyServiceApp。 - QA阶段同理,变量值设为
QA_MyService和QA_MyServiceApp。
- 进入发布流水线的某个阶段(比如DEV阶段),打开「变量」选项卡,添加变量
配置Service Fabric部署任务的参数覆盖:
在每个阶段的Azure Service Fabric Deploy任务里,找到「Application Parameter Overrides」选项,添加如下配置:MyServiceInstanceName=$(ServiceInstanceName);MyAppInstanceName=$(AppInstanceName)这样任务在部署时,会自动把应用包中的参数替换成当前阶段的变量值。
确认部署模式设置:
确保Deploy任务的「Action」选项选择「Create Or Upgrade Application」——因为我们是在同一个集群里创建新的应用实例,而不是升级已有的实例,这个设置能确保即使是首次部署新名称的实例,也能成功创建。
额外注意事项
- 如果你的服务是有状态服务,记得还要把分区方案、实例计数这些和环境相关的配置也参数化,比如在
ServiceManifest.xml里设置参数,然后在ApplicationManifest.xml里引用,最后在发布流水线的变量里配置对应值。 - 同一制品的服务类型版本是固定的,首次部署某个实例时会自动在集群注册服务类型,后续部署其他实例时因为类型版本相同,不会重复注册,完全没问题。
- 如果你需要给不同实例配置不同的服务配置(比如连接字符串),可以用同样的参数化思路,在
Settings.xml里设置参数,然后在发布流水线的变量里覆盖。
内容的提问来源于stack exchange,提问作者Damian

