# 基于Nginx实现应用的灰度发布
#### 应用场景
在用户进行新系统升级时，会遇到停服部署或者无法灰度验证的情况，本实践采用基于Nginx负载均衡机制，在不影响业务正常运行的前提下，实现系统的平滑升级。
#### 方案架构
系统升级时，若采用蓝绿部署方式，开发人员需进行如下操作：
1. 先将A边服务器（原蓝环境）下线，同时访问流量将全部切分到B边服务器，此时对A边服务器进行升级操作。
2. A边服务器升级完毕后，将A边服务器设为灰度测试环境，由测试人员对A边服务器进行灰度验证。
3. 灰度验证完毕且功能正常后，A边业务服务器（绿环境）正式上线，并将所有流量切分到A边业务服务器，此时蓝绿部署完毕。
4. 在服务运行过程中，如果A边服务器出现紧急情况，执行蓝绿倒换实现业务快速恢复。
若采用金丝雀灰度部署方式（即灰度发布），再重复前面的操作，将B边服务器进行升级，并完成灰度测试及正式上线，此时就完成新系统的灰度发布。
#### 前提条件
- 已有可用项目，如果没有，请先[新建 CodeArts 项目](https://support.huaweicloud.com/usermanual-devcloud/codearts_01_0027.html)。
- 具有创建应用的权限，参考[权限管理](https://support.huaweicloud.com/usermanual-deployman/deployman_hlp_0035.html)。
- 已有目标业务服务器：**A_test** 与**B_test**，且业务服务器已有应用服务正在运行。本实践以Linux系统为例。
- 已有反向代理服务器：**Gray_release**。本实践以Linux系统为例。
- 已有灰度验证主机，该主机代表灰度测试人员。
- 要确保各服务器之间可以相互通信，例如：将所有服务器加到同一VPC下。
 
#### 操作流程
本文介绍基于Nginx负载均衡机制，实现主机部署场景的蓝绿发布和灰度发布能力，关于Nginx更多信息请参考[Nginx官网](https://nginx.org/en/docs/beginners_guide.html)。
#### 步骤一：为反向代理服务器安装并启动Nginx节点（可选）
若您的反向代理服务器已安装并启动Nginx节点，则本步骤跳过。
1. 新建基础资源。 
   1. 进入CodeArts首页，单击目标项目名称，进入目标项目下。
   
   2. 单击菜单**"设置 \> 通用设置 \> 基础资源管理"** ，默认进入**"主机集群"** 页面。
      或单击菜单**"持续交付 \> 部署"** ，进入项目下部署服务界面。单击"**基础资源管理"** 默认进入**"主机集群"**页面。
      
   
   3. 单击**"新建主机集群"** ，填写集群名称、操作系统、使用代理机接入、执行主机及描述等基本信息后，单击**"保存"**，完成主机集群的创建。
   
   4. 单击**"添加或导入主机"** ，选择**"通过IP手动添加"** ，填写主机名（例如**：A_test、B_test、Gray_release** ）、IP、用户名、密码/密钥、ssh端口信息后，单击**"确定"** ，重复操作完成三台目标主机的创建，并单击"连通性验证"进行连通性验证操作。关于连通性验证问题，请参考[主机管理常见问题](https://support.huaweicloud.com/deployman_faq/deployman_faq_0000.html)排查。
      ![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000002245691960.png "点击放大")
      
      
   
   
   
   
2. 新建应用。 
   1. 单击菜单**"持续交付 \> 部署"**进入到部署服务页面。
   
   2. 单击"**新建应用** "，进入**"基本信息"**页面，可根据需要修改名称、描述、执行主机等基本信息。
   
   3. 完成应用基本信息的编辑后，单击**"下一步"**，进入选择部署模板页面。
   
   4. 选择**"空白模板"** ，单击**"确定"** ，进入**"部署步骤"**页签。
   
   
   
   
3. 编辑应用。 
   1. 切换到**"环境管理"** 页签，添加并编辑环境。
      - 单击**"新建环境"** ，填写环境名，例如**：** **反向代理服务器组**，选择与服务器对应的操作系统，填写描述信息等。
      
      - 单击**"保存"**，完成环境的创建。
      
      - 单击**"导入主机"** ，系统已自动筛选符合当前环境的所有集群，在弹框中选择目标主机集群，单击目标主机操作列的![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000001919020272.png)图标，即可将该主机导入环境中。
       
   
   2. 切换到**"部署步骤"** 页签，添加并编辑以下步骤。
      - 添加**"安装Nginx"** 步骤，并修改为下表参数（以Linux系统为例）。
        表1参数填写说明 
        | 参数         | 是否必填 | 填写说明                                                                                                                       |
        |:---|:---|:---|
        | 步骤显示名称    | 是  | 步骤添加后在部署步骤显示的名称，可保持默认。 仅支持汉字、英文字母、数字、空格、或-_,;:./()（）符号，其中空格不可在名称开头或结尾使用，长度为1-128。 |
        | 环境         | 是  | 选择"反向代理服务器组"。                                                                                                                |
        | Nginx版本     | 是   | 选择目标版本。示例：nginx-1.14.2。                                                                                                     |
        | Nginx安装路径 | 是    | 目标环境中Nginx服务的安装路径。示例：/usr/local/nginx。                                                                                     |
           
        
      
      - 添加**"启动/停止Nginx"** 步骤，并修改为下表参数（以Linux系统为例）。
        表2参数填写说明 
        | 参数         | 是否必填 | 填写说明                                                                                                                        |
        |:---|:---|:---|
        | 步骤显示名称     | 是     | 步骤添加后在部署步骤显示的名称，可保持默认。 仅支持汉字、英文字母、数字、空格、或-_,;:./()（）符号，其中空格不可在名称开头或结尾使用，长度为1-128。 |
        | 环境         | 是      | 选择**"反向代理服务器组"**。                                                                                                            |
        | 操作类型        | 是      | 选择**"启动（nginx）"**。                                                                                                           |
        | Nginx安装的路径 | 是      | 目标环境中Nginx服务的安装路径。 示例：/usr/local/nginx。                                         |
           
        
       
   
   3. 单击**"保存并部署"**，开始部署应用。
   
   
   ![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000002245853446.png "点击放大")
   
   
4. 部署应用。 
   部署完成后，应用状态栏的颜色变成绿色，并显示"**部署成功**"，则表示此次部署应用成功。
   若应用状态栏的颜色变成红色，并显示"**部署失败** "，则表示此次部署应用失败，请单击"**查看解决方案**"链接查看解决方法。
   更多部署问题，请参考[应用部署常见问题](https://support.huaweicloud.com/deployman_faq/deployman_faq_00002.html)排查。
   
   
 
#### 步骤二：新建并编辑应用一（A边节点灰度部署）
1. 新建应用。 
   1. 单击菜单**"持续交付 \> 部署"**进入到部署服务页面。
   
   2. 单击**"** **新建应用** **"** ，进入**"基本信息"**页面，可根据需要修改名称、描述、执行主机等基本信息。
   
   3. 完成应用基本信息的编辑后，单击**"下一步"**，进入选择部署模板页面。
   
   4. 选择**"通用部署"** 模板，单击**"确定"**。
   
   
   
   
2. 编辑应用。 
   1. 切换到**"环境管理"** 页签，添加并编辑环境。
      - 单击**"新建环境"** ，填写环境名，例如**：** **反向代理服务器组**，选择与服务器对应的操作系统，填写描述信息等。
      
      - 单击**"保存"**，完成环境的创建。
      
      - 单击**"导入主机"** ，系统已自动筛选符合当前环境的所有集群，在弹框中选择目标主机集群，单击目标主机操作列的![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000001948499181.png)图标，即可将该主机导入环境中。
      
      - 重复上面操作步骤，完成新建**"** **目标业务服务器组_A边节点** **"** 并添加**"** **A_test** **"**服务器的操作。
       
   
   2. 切换到**"参数设置"** 页签，新增如下参数。
      ![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000002143654012.png "点击放大")
      
      表3参数填写说明 
      | 参数    | 是否必填 | 填写说明                                                                                                                                                                                                                      |
      |:---|:---|:---|
      | 名称      | 是      | 参数名称。可修改自定义参数名称。 自定义参数名称不可与系统预定义参数名称相同。 仅支持以字母开头，英文、数字和_组成，长度为1-128字符。 示例：app_name和service_port。 |
      | 类型      | 是     | 参数可选类型，包括：字符串类型、枚举类型和环境类型。 此处选择字符串类型。                                                                                                                                               |
      | 默认值    | 否    | 根据需要填写/选择参数值。 示例：test和3000。                                                                                                                                                   |
      | 私密参数   | 否      | 参数为私密参数时，系统会将输入参数做加密存储，使用时进行解密，不可设置**"** **运行时设置** **"**。 此处保持默认不开启。                                                                                                              |
      | 运行时设置 | 否       | 打开"运行时设置"开关，表示部署应用时支持变更参数值，并且也会把该参数上报应用。 此处保持默认不开启。                                                                                                                              |
      | 参数描述   | 否      | 对本参数的描述。                                                                                                                                                                                                                |
         
      
   
   3. 切换到**"部署步骤"** 页签，添加并编辑以下步骤。
      - 添加**"启动/停止Nginx"** 步骤，并修改为下表参数（以Linux系统为例）。
        表4参数填写说明 
        | 参数              | 是否必填 | 填写说明                                                                                                                                                                  |
        |:---|:---|:---|
        | 步骤显示名称          | 是   | 步骤添加后在部署步骤显示的名称。 仅支持汉字、英文字母、数字、空格、或-_,;:./()（）符号，其中空格不可在名称开头或结尾使用，长度为1-128。 示例：A边节点下线。 |
        | 环境            | 是 | 选择目标环境。 示例：反向代理服务器组。                                                                                                         |
        | 操作类型           | 是   | 选择操作类型。 示例：重载配置文件（reload）。                                                                                                   |
        | Nginx安装的路径     | 是     | 目标环境中Nginx服务的安装路径。示例：/usr/local/nginx。                                                                                                                                   |
        | 是否在操作之前修改配置文件  | 否  | 此次配置请勾选。                                                                                                                                                               |
        | 要修改的Nginx配置文件路径 | 是   | 目标主机中Nginx配置文件所在路径。 示例：/usr/local/nginx/conf/nginx.conf。                                                                     |
        | 配置文件备份路径       | 否  | 目标主机中原Nginx配置文件备份目标路径。 示例：/usr/local/nginx/conf/nginx_bak.conf。                                                                |
        | 配置文件内容          | 是  | 新配置文件内容。 示例：见附录中[A边节点下线-代码示例]。                                                       |
           
        
      
      - 编辑**"下载软件包"** 步骤，并修改为下表参数（以Linux系统为例）。
        表5参数填写说明 
        | 参数          | 是否必填 | 填写说明                                                                                                                                                                         |
        |:---|:---|:---|
        | 步骤显示名称      | 是   | 步骤添加后在部署步骤显示的名称。 仅支持汉字、英文字母、数字、空格、或-_,;:./()（）符号，其中空格不可在名称开头或结尾使用，长度为1-128。 示例：A边节点下载软件包。 |
        | 选择源类型      | 是     | 选择源类型。 示例：制品仓库。                                                                                                                    |
        | 环境           | 是  | 选择目标环境。 示例：目标业务服务器组_A边节点。                                                                                                           |
        | 选择软件包       | 是      | 选择制品仓库中需要部署的软件包。                                                                                                                                                            |
        | 下载到主机的部署目录 | 是    | 软件包下载到目标主机的路径。 示例：/usr/local/。                                                                                                   |
           
        
      
      - 编辑**"执行部署脚本"** 步骤，并修改为下表参数（以Linux系统为例）。
        表6参数填写说明 
        | 参数     | 是否必填 | 填写说明                                                                                                                                                                    |
        |:---|:---|:---|
        | 步骤显示名称  | 是       | 步骤添加后在部署步骤显示的名称。 仅支持汉字、英文字母、数字、空格、或-_,;:./()（）符号，其中空格不可在名称开头或结尾使用，长度为1-128。 示例：部署A边节点。 |
        | 环境      | 是      | 选择目标环境。 示例：目标业务服务器组_A边节点。                                                                                                        |
        | shell命令 | 是     | 填写待执行命令。 示例：见附录中[部署节点]。                                                              |
           
        
      
      - 添加**"启动/停止Nginx"** 步骤，并修改为下表参数（以Linux系统为例）。
        表7参数填写说明 
        | 参数               | 是否必填 | 填写说明                                                                                                                                                                      |
        |:---|:---|:---|
        | 步骤显示名称          | 是    | 步骤添加后在部署步骤显示的名称。 仅支持汉字、英文字母、数字、空格、或-_,;:./()（）符号，其中空格不可在名称开头或结尾使用，长度为1-128。 示例：A边节点灰度上线。 |
        | 环境             | 是      | 选择目标环境。 示例：反向代理服务器组。                                                                                                           |
        | 操作类型             | 是     | 选择操作类型。 示例：重载配置文件（reload）。                                                                                                      |
        | Nginx安装的路径         | 是  | 目标环境中Nginx服务的安装路径。 示例：/usr/local/nginx。                                                                                          |
        | 是否在操作之前修改配置文件     | 否     | 此次配置请勾选。                                                                                                                                                                   |
        | 要修改的Nginx配置文件路径 | 是     | 目标主机中Nginx配置文件所在路径。 示例：/usr/local/nginx/conf/nginx.conf。                                                                      |
        | 配置文件备份路径         | 否     | 目标主机中原Nginx配置文件备份目标路径。 示例：/usr/local/nginx/conf/nginx_bak.conf。                                                                   |
        | 配置文件内容           | 是     | 新配置文件内容。 示例：见附录中[A边节点灰度上线-代码示例]。                                                     |
           
        
      
      - 编辑**"健康测试"** 步骤，并修改为下表参数（以Linux系统为例）。
        表8参数填写说明 
        | 参数        | 是否必填 | 填写说明                                                                                                                                                                         |
        |:---|:---|:---|
        | 步骤显示名称 | 是     | 步骤添加后在部署步骤显示的名称。 仅支持汉字、英文字母、数字、空格、或-_,;:./()（）符号，其中空格不可在名称开头或结尾使用，长度为1-128。 示例：A边健康测试。 |
        | 环境      | 是    | 选择目标环境。示例：目标业务服务器组_A边节点。                                                                                                                                                    |
        | 重试次数      | 是     | 失败后重试次数，超过预设的重试次数，服务未启动会导致URL检测失败。 示例：1。                                                                                        |
        | 间隔时间      | 是     | 每次重试测试的间隔时间（s）。 示例：60。                                                                                                            |
        | 测试路径    | 是   | URL健康测试，支持添加多个。 示例：http://127.0.0.1:3000（应用服务的IP及端口）。                                                                              |
           
        
       
   
   
   
   
3. 单击**"保存"** ，应用创建完成。
   
   ![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000001948499193.png "点击放大")
   
   
 
#### 步骤三：新建并编辑应用二（A边节点上线）
1. 新建应用。 
   1. 单击"**新建应用** "，进入**"基本信息"**页面，可根据需要修改名称、描述、执行主机等基本信息。
   
   2. 完成应用基本信息的编辑后，单击**"下一步"**，进入选择部署模板页面。
   
   3. 选择**"空白模板"** ，单击**"确定"**。
   
   
   
   
2. 编辑应用。 
   1. 切换到**"环境管理"** 页签，添加并编辑环境。
      - 单击**"新建环境"** ，填写环境名，例如**：** **反向代理服务器组**，选择与服务器对应的操作系统，填写描述信息等。
      
      - 单击**"保存"**，完成环境的创建。
      
      - 单击**"导入主机"** ，系统已自动筛选符合当前环境的所有集群，在弹框中选择目标主机集群，单击目标主机操作列的![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000001919020276.png)图标，即可将该主机导入环境中。
       
   
   2. 切换到**"部署步骤"** 页签，添加并编辑以下步骤。
      添加**"启动/停止Nginx"** ，并修改为下表参数（以Linux系统为例）。
      表9参数填写说明 
      | 参数              | 是否必填 | 填写说明                                                                                                                                                                     |
      |:---|:---|:---|
      | 步骤显示名称          | 是     | 步骤添加后在部署步骤显示的名称。 仅支持汉字、英文字母、数字、空格、或-_,;:./()（）符号，其中空格不可在名称开头或结尾使用，长度为1-128。 示例：A边节点上线。 |
      | 环境             | 是     | 选择目标环境。 示例：反向代理服务器组。                                                                                                           |
      | 操作类型            | 是      | 选择操作类型。 示例：重载配置文件（reload）。                                                                                                       |
      | Nginx安装的路径      | 是     | 目标环境中Nginx服务的安装路径。 示例：/usr/local/nginx。                                                                                         |
      | 是否在操作之前修改配置文件  | 否    | 此次配置请勾选。                                                                                                                                                                   |
      | 要修改的Nginx配置文件路径 | 是     | 目标主机中Nginx配置文件所在路径。 示例：/usr/local/nginx/conf/nginx.conf。                                                                       |
      | 配置文件备份路径        | 否    | 目标主机中原Nginx配置文件备份目标路径。 示例：/usr/local/nginx/conf/nginx_bak.conf。                                                                |
      | 配置文件内容          | 是    | 新配置文件内容。 示例：见附录中[节点上线-代码示例]。                                                       |
         
      
   
   
   
   
3. 单击**"保存"** ，应用创建完成。
   
   ![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000001919180176.png "点击放大")
   
   
 
#### 步骤四：新建并编辑应用三（B边节点灰度部署）
1. 复制应用。 
   单击![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000001919020264.png)图标，单击**"复制"**，完成应用的复制。
   ![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000002178864157.png "点击放大")
   
   
   
2. 编辑应用。 
   1. 切换到**"环境管理"** 页签，添加并编辑环境。
      - 单击**"新建环境"** ，填写环境名，例如**：** **反向代理服务器组**，选择与服务器对应的操作系统，填写描述信息等。
      
      - 单击**"保存"**，完成环境的创建。
      
      - 单击**"导入主机"** ，系统已自动筛选符合当前环境的所有集群，在弹框中选择目标主机集群，单击目标主机操作列的![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000001919180180.png)图标，即可将该主机导入环境中。
      
      - 重复上面操作步骤，完成新建**"** **目标业务服务器组_B边节点** **"** 并添加**"** **B_test** **"**服务器的操作。
       
   
   2. 切换到**"部署步骤"** 页签，添加并编辑以下步骤。
      - 编辑**"A边节点下线"** 步骤，并修改为下表参数（以Linux系统为例）。
        表10参数填写说明 
        | 参数                | 是否必填 | 填写说明                                                                                                                                                                     |
        |:---|:---|:---|
        | 步骤显示名称          | 是  | 步骤添加后在部署步骤显示的名称。 仅支持汉字、英文字母、数字、空格、或-_,;:./()（）符号，其中空格不可在名称开头或结尾使用，长度为1-128。 示例：B边节点下线。 |
        | 环境              | 是  | 选择目标环境。 示例：反向代理服务器组。                                                                                                            |
        | 操作类型             | 是   | 选择操作类型。 示例：重载配置文件（reload）。                                                                                                    |
        | Nginx安装的路径      | 是 | 目标环境中Nginx服务的安装路径。 示例：/usr/local/nginx。                                                                                        |
        | 是否在操作之前修改配置文件   | 否  | 此次配置请勾选。                                                                                                                                                                 |
        | 要修改的Nginx配置文件路径 | 是  | 目标主机中Nginx配置文件所在路径。 示例：/usr/local/nginx/conf/nginx.conf。                                                                        |
        | 配置文件备份路径        | 否  | 目标主机中原Nginx配置文件备份目标路径。 示例：/usr/local/nginx/conf/nginx_bak.conf。                                                                 |
        | 配置文件内容           | 是 | 新配置文件内容。 示例：见附录中[B边节点下线-代码示例]。                                                      |
           
        
      
      - 编辑**"A边节点下载软件包"** 步骤，并修改为下表参数（以Linux系统为例）。
        表11参数填写说明 
        | 参数         | 是否必填 | 填写说明                                                                                                                                                                          |
        |:---|:---|:---|
        | 步骤显示名称        | 是     | 步骤添加后在部署步骤显示的名称。 仅支持汉字、英文字母、数字、空格、或-_,;:./()（）符号，其中空格不可在名称开头或结尾使用，长度为1-128。 示例：B边节点下载软件包。 |
        | 选择源类型      | 是    | 选择源类型。 示例：制品仓库。                                                                                                                 |
        | 环境            | 是      | 选择目标环境。 示例：目标业务服务器组_B边节点。                                                                                                          |
        | 选择软件包      | 是      | 选择制品仓库中需要部署的软件包。                                                                                                                                                            |
        | 下载到主机的部署目录 | 是     | 软件包下载到目标主机的路径。 示例：/usr/local/。                                                                                                      |
           
        
      
      - 编辑**"部署A边节点"** 步骤，并修改为下表参数（以Linux系统为例）。
        表12参数填写说明 
        | 参数      | 是否必填 | 填写说明                                                                                                                                                                     |
        |:---|:---|:---|
        | 步骤显示名称    | 是   | 步骤添加后在部署步骤显示的名称。 仅支持汉字、英文字母、数字、空格、或-_,;:./()（）符号，其中空格不可在名称开头或结尾使用，长度为1-128。 示例：部署B边节点。 |
        | 环境       | 是    | 选择目标环境。 示例：目标业务服务器组_B边节点。                                                                                                        |
        | shell命令 | 是   | 填写待执行命令。 示例：见附录中[部署节点]。                                                               |
           
        
      
      - 编辑**"A边节点灰度上线"** 步骤，并修改为下表参数（以Linux系统为例）。
        表13参数填写说明 
        | 参数               | 是否必填 | 填写说明                                                                                                                                                                    |
        |:---|:---|:---|
        | 步骤显示名称            | 是   | 步骤添加后在部署步骤显示的名称。 仅支持汉字、英文字母、数字、空格、或-_,;:./()（）符号，其中空格不可在名称开头或结尾使用，长度为1-128。 示例：B边节点灰度上线。 |
        | 环境              | 是    | 选择目标环境。示例：反向代理服务器组。                                                                                                                                                   |
        | 操作类型              | 是     | 选择操作类型。示例：重载配置文件（reload）。                                                                                                                                              |
        | Nginx安装的路径     | 是    | 目标环境中Nginx服务的安装路径。示例：/usr/local/nginx。                                                                                                                                |
        | 是否在操作之前修改配置文件   | 否     | 此次配置请勾选。                                                                                                                                                            |
        | 要修改的Nginx配置文件路径 | 是     | 目标主机中Nginx配置文件所在路径。 示例：/usr/local/nginx/conf/nginx.conf。                                                                      |
        | 配置文件备份路径           | 否     | 目标主机中原Nginx配置文件备份目标路径。 示例：/usr/local/nginx/conf/nginx_bak.conf。                                                              |
        | 配置文件内容           | 是    | 新配置文件内容。 示例：见附录中[B边节点灰度上线-代码示例]。                                                |
           
        
      
      - 编辑**"A边健康测试"** 步骤，并修改为下表参数（以Linux系统为例）。
        表14参数填写说明 
        | 参数    | 是否必填 | 填写说明                                                                                                                                                                    |
        |:---|:---|:---|
        | 步骤显示名称 | 是    | 步骤添加后在部署步骤显示的名称。 仅支持汉字、英文字母、数字、空格、或-_,;:./()（）符号，其中空格不可在名称开头或结尾使用，长度为1-128。 示例：B边健康测试。 |
        | 环境    | 是     | 选择目标环境。示例：目标业务服务器组_B边节点。                                                                                                                                                  |
        | 重试次数  | 是     | 失败后重试次数，超过预设的重试次数，服务未启动会导致URL检测失败。 示例：1。                                                                                       |
        | 间隔时间  | 是       | 每次重试测试的间隔时间（s）。 示例：60。                                                                                                          |
        | 测试路径   | 是   | URL健康测试，支持添加多个。 示例：http://127.0.0.1:3000（应用服务的IP及端口）。                                                                         |
           
        
       
   
   
   
   
3. 单击**"保存"** ，应用创建完成。
   
   ![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000001919180200.png "点击放大")
   
   
 
#### 步骤五：新建并编辑应用四（B边节点上线）
1. 复制应用。 
   单击![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000001948499213.png)图标，单击**"复制"**，完成应用的复制。
   
   
2. 编辑应用。 
   1. 切换到**"环境管理"** 页签，添加并编辑环境。
      - 单击**"新建环境"** ，填写环境名，例如**：** **反向代理服务器组**，选择与服务器对应的操作系统，填写描述信息等。
      
      - 单击**"保存"**，完成环境的创建。
      
      - 单击**"导入主机"** ，系统已自动筛选符合当前环境的所有集群，在弹框中选择目标主机集群，单击目标主机操作列的![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000001948499157.png)图标，即可将该主机导入环境中。
       
   
   2. 切换到**"部署步骤"** 页签，添加并编辑以下步骤。
      编辑**"A边节点上线"** ，并修改为下表参数（以Linux系统为例）。
      表15参数填写说明 
      | 参数               | 是否必填 | 填写说明                                                                                                                                                                  |
      |:---|:---|:---|
      | 步骤显示名称          | 是    | 步骤添加后在部署步骤显示的名称。 仅支持汉字、英文字母、数字、空格、或-_,;:./()（）符号，其中空格不可在名称开头或结尾使用，长度为1-128。 示例：B边节点上线。 |
      | 环境              | 是    | 选择目标环境。示例：反向代理服务器组。                                                                                                                                                 |
      | 操作类型            | 是    | 选择操作类型。示例：重载配置文件（reload）。                                                                                                                                           |
      | Nginx安装的路径        | 是  | 目标环境中Nginx服务的安装路径。示例：/usr/local/nginx。                                                                                                                              |
      | 是否在操作之前修改配置文件   | 否   | 此次配置请勾选。                                                                                                                                                            |
      | 要修改的Nginx配置文件路径 | 是   | 目标主机中Nginx配置文件所在路径。示例：/usr/local/nginx/conf/nginx.conf。                                                                                                               |
      | 配置文件备份路径           | 否     | 目标主机中原Nginx配置文件备份目标路径。示例：/usr/local/nginx/conf/nginx_bak.conf。                                                                                                      |
      | 配置文件内容            | 是  | 新配置文件内容。示例：见附录中[节点上线-代码示例]。                                                                                                |
         
      
   
   
   
   
3. 单击**"保存"** ，应用创建完成。
   
   ![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000001948499209.png "点击放大")
   
   
 
#### 步骤六：新建并编辑流水线
1. 新建流水线。 
   - 单击菜单**"持续交付 \> 流水线"**进入到流水线服务页面。
   
   - 单击**"新建流水线"** ，选择**"所属项目"** ，输入**"名称"** ，流水线源选择**"暂不选择"** ，单击**"下一步"**。
   
   - 模板选择**"空模板"** ，单击**"确定"** 。
     ![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000002143710850.png "点击放大")
     
     
   
   
   
   
2. 编辑流水线阶段任务一（**A边节点灰度部署** ）。
   
   - 单击![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000001948499185.png)，将弹框中的参数修改为如下参数并单击**"确定"** 。
     表16参数填写说明 
     | 参数   | 是否必填 | 填写说明              |
     |:---|:---|:---|
     | 阶段名称 | 是    | 示例：**A边节点灰度部署**。 |
     | 总是运行   | 是     | 选择**"否"**。         |
        
     
   
   - 单击![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000001919180172.png)图标，在弹框中选择准入类型为**"自动"** ，单击**"确定"**。
   
   - 单击**"新建任务"** ，单击**"部署"** ，选择**"CodeArtsDeploy部署"** ，单击**"添加"** ，将弹框中的参数修改为如下参数并单击**"确定"** 。![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000002280775085.png "点击放大")
     表17参数填写说明 
     | 参数        | 是否必填 | 填写说明                        |
     |:---|:---|:---|
     | 名称      | 是 | 示例：**A边节点灰度部署**。             |
     | 请选择需要调用的任务 | 是  | 选择**"** **A边节点灰度部署** **"**。 |
     | 关联构建任务                                  | 否 | 暂不选择。                                                   |
        
     
   
   
   
   
3. 新建并编辑流水线阶段任务二（**A边节点上线** ）。
   
   - 单击![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000002143715122.png)图标，单击![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000001948499161.png)，将弹框中的参数修改为如下参数并单击**"确定"** 。
     表18参数填写说明 
     | 参数      | 是否必填 | 填写说明             |
     |:---|:---|:---|
     | 名称   | 是     | 示例：**A边节点上线**。 |
     | 总是运行 | 是      | 选择**"否"**。       |
        
     
   
   - 单击![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000001919180212.png)图标，在弹框中选择准入类型为**"自动"** ，单击**"确定"**。
   
   - 单击**"新建任务"** ，单击**"通用 \> 人工审核 \> 添加"** ，将弹框中的参数修改为如下参数并单击**"确定"** 。
     表19参数填写说明 
     | 参数      | 是否必填 | 填写说明                    |
     |:---|:---|:---|
     | 名称      | 是     | 示例：A边节点灰度验证。              |
     | 审核人   | 是    | 选择业务验证人员。            |
     | 审核模式 | 是    | 选择**"全部人审核"**。        |
     | 超时处理 | 是     | 选择**"审核失败，流水线终止执行"**。 |
     | 审核时长  | 是    | 示例：4小时。               |
     | 审核说明  | 否   | 填写相关审核说明。               |
        
     
   
   - 如下图所示，单击![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000002179036289.png)图标，单击**"部署"** ，选择**"CodeArtsDeploy部署"** ，单击**"添加"** ，将弹框中的参数修改为如下参数并单击**"确定"** 。
     ![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000002143717506.png)
     表20参数填写说明 
     | 参数          | 是否必填 | 填写说明                     |
     |:---|:---|:---|
     | 名称         | 是  | 示例：**A边节点上线**。          |
     | 请选择需要调用的任务 | 是    | 选择**"** **A边节点上线** **"**。 |
     | 关联构建任务       | 否   | 暂不选择。                    |
        
     
   
   
   
   
4. 编辑流水线阶段任务三（**B边节点灰度部署** ）。
   
   - 单击![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000002178925193.png)图标，单击![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000001948499177.png)，将弹框中的参数修改为如下参数并单击**"确定"** 。
     表21参数填写说明 
     | 参数   | 是否必填 | 填写说明             |
     |:---|:---|:---|
     | 名称  | 是     | 示例：**B边节点灰度部署**。 |
     | 总是运行 | 是    | 选择**"否"**。      |
        
     
   
   - 单击![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000001919180204.png)图标，在弹框中选择准入类型为**"自动"** ，单击**"确定"**。
   
   - 单击**"新建任务"** ，单击**"部署"** ，选择**"CodeArtsDeploy部署"** ，单击**"添加"** ，将弹框中的参数修改为如下参数并单击**"确定"** 。
     表22参数填写说明 
     | 参数        | 是否必填 | 填写说明                       |
     |:---|:---|:---|
     | 名称         | 是  | 示例：**B边节点灰度部署**。            |
     | 请选择需要调用的任务 | 是    | 选择**"** **B边节点灰度部署** **"**。 |
     | 关联构建任务     | 否   | 暂不选择。                       |
        
     
   
   
   
   
5. 新建并编辑流水线阶段任务四（**B边节点上线** ）。
   
   - 单击![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000002179043549.png)图标，单击![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000001919020280.png)，将弹框中的参数修改为如下参数并单击**"确定"** 。
     表23参数填写说明 
     | 参数     | 是否必填 | 填写说明           |
     |:---|:---|:---|
     | 名称     | 是     | 示例：**B边节点上线**。 |
     | 总是运行 | 是     | 选择**"否"**。      |
        
     
   
   - 单击![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000001919180196.png)图标，在弹框中选择准入类型为**"自动"** ，单击**"确定"**。
   
   - 单击**"新建任务"** ，单击**"通用 \> 人工审核 \> 添加"** ，将弹框中的参数修改为如下参数并单击**"确定"** 。
     表24参数填写说明 
     | 参数  | 是否必填 | 填写说明                    |
     |:---|:---|:---|
     | 名称    | 是    | 示例：B边节点灰度验证。           |
     | 审核人   | 是   | 选择业务验证人员。             |
     | 审核模式  | 是   | 选择**"全部人审核"**。         |
     | 超时处理  | 是    | 选择**"审核失败，流水线终止执行"**。 |
     | 审核时长 | 是    | 示例：4小时。               |
     | 审核说明  | 否    | 填写相关审核说明。               |
        
     
   
   - 如下图所示，单击![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000002143724198.png)图标，单击**"部署"** ，选择**"CodeArtsDeploy部署"** ，单击**"添加"** ，将弹框中的参数修改为如下参数并单击**"确定"** 。
     ![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000002143718194.png)
     表25参数填写说明 
     | 参数         | 是否必填 | 填写说明                       |
     |:---|:---|:---|
     | 名称         | 是    | 示例：**B边节点上线**。             |
     | 请选择需要调用的任务 | 是     | 选择**"** **B边节点上线** **"**。 |
     | 关联构建任务     | 否     | 暂不选择。                    |
        
     
   
   
   
   
6. 完成以上操作后，单击**"保存并运行"** ，开始运行流水线任务。
   
   ![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000002178924137.png "点击放大")
   
   
   
 
#### 步骤七：运行流水线并手动进行灰度验证A、B边节点是否正常
当流水线执行到上线A边节点或上线B边节点时，流水线暂停执行，需要灰度用户手动验证灰度环境下的A边、B边业务服务器是否正常，业务正常后再继续运行流水线。
灰度用户可使用"curl"命令验证灰度环境系统是否正常。
```
curl http://反向代理服务器IP:Nginx端口
```
查看灰度用户是否进入到目标灰度环境服务器，可登录**反向代理服务器**，进入logs/access.log路径查看日志，显示如下图则代表正常。
![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000002247905593.png "点击放大")
#### 附录
- **A边节点下线-代码示例**
  ```
  worker_processes  1;
  events {
      worker_connections  1024;
  }
  http {
      include       mime.types;
      default_type  application/octet-stream;
      log_format main  '$time_local|$remote_addr[$remote_port]|$request|$request_method|$content_length|'
          '$content_type|$http_referer|$host|$http_x_forwarded_for|'
          '$http_true_client_ip|$server_name|$request_uri|$server_addr|$server_port|'
          '$status|$request_time|$upstream_addr|$upstream_response_time|$cookie_domain_tag';
      access_log logs/access.log main; #访问日志：存放路径，日志级别。
      error_log logs/error.log; #错误日志：存放路径。
      sendfile        on;
      keepalive_timeout  65;
      upstream portal {
          # 下面填入A主机IP及应用服务端口
          #server X.X.X.X:X;      #A节点下线
          # 下面填入B主机IP及应用服务端口
          server X.X.X.X:X;
      }
      upstream portal_test {
          # 下面填入A主机IP及应用服务端口
          server X.X.X.X:X;
          # 下面填入B主机IP及应用服务端口
          server X.X.X.X:X;
      }
      
      server {
          listen       XXX;#填入Nginx端口
          server_name  localhost;
          
          location / {
              set $backend portal;
              set $test portal_test;
              #下面填入灰度验证机器IP
              #if ( $remote_addr ~* "X.X.X.X") {
              #    set $backend $test;
              #}
              proxy_pass https://$backend;
          }
          error_page   500 502 503 504  /50x.html;
          location = /50x.html {
              root   html;
          }
     }
  }
  ```
  
- **部署节点**
  ```
  # 获取应用进程id
  pid=`ps -ef | grep app_name | grep -v grep | awk '{print $2}'`
  if [ -z "$pid" ];
  then
    echo "[app_name pid is not exist.]"
  else
    echo "app_name pid: $pid "
    # 停止该进程
    kill -15 $pid
  fi
  # 重新启动应用，可通过执行部署脚本和部署命令两种方式启动应用，如下：
  # 方式一：通过执行部署脚本启动应用
  # sh startup.sh
  # 方式二：通过执行命令启动应用，建议采用nohup后台启动方式
  # nohup java -jar /usr/local/app/SpringbootDemo.jar &
  ```
  
- **A边节点灰度上线-代码示例**
  ```
  worker_processes  1;
  events {
      worker_connections  1024;
  }
  http {
      include       mime.types;
      default_type  application/octet-stream;
      log_format main  '$time_local|$remote_addr[$remote_port]|$request|$request_method|$content_length|'
          '$content_type|$http_referer|$host|$http_x_forwarded_for|'
          '$http_true_client_ip|$server_name|$request_uri|$server_addr|$server_port|'
          '$status|$request_time|$upstream_addr|$upstream_response_time|$cookie_domain_tag';
      access_log logs/access.log main; #访问日志：存放路径，日志级别。
      error_log logs/error.log; #错误日志：存放路径。
      sendfile        on;
      keepalive_timeout  65;
      upstream portal {
          # 下面填入A主机IP及应用服务端口
          #server X.X.X.X:X;      #A节点下线
          # 下面填入B主机IP及应用服务端口
          server X.X.X.X:X;
      }
      upstream portal_test {
          # 下面填入A主机IP及应用服务端口
          server X.X.X.X:X;       #A节点灰度上线
          # 下面填入B主机IP及应用服务端口
          #server X.X.X.X:X;
      }
      
      server {
          listen       XXX;#填入Nginx端口
          server_name  localhost;
          
          location / {
              set $backend portal;
              set $test portal_test;
              #下面填入灰度验证机器IP
              if ( $remote_addr ~* "X.X.X.X") {
                  set $backend $test;
              }
              proxy_pass https://$backend;
          }
          error_page   500 502 503 504  /50x.html;
          location = /50x.html {
              root   html;
          }
     }
  }
  ```
  
- **B边节点下线-代码示例**
  ```
  worker_processes  1;
  events {
      worker_connections  1024;
  }
  http {
      include       mime.types;
      default_type  application/octet-stream;
      log_format main  '$time_local|$remote_addr[$remote_port]|$request|$request_method|$content_length|'
          '$content_type|$http_referer|$host|$http_x_forwarded_for|'
          '$http_true_client_ip|$server_name|$request_uri|$server_addr|$server_port|'
          '$status|$request_time|$upstream_addr|$upstream_response_time|$cookie_domain_tag';
      access_log logs/access.log main; #访问日志：存放路径，日志级别。
      error_log logs/error.log; #错误日志：存放路径。
      sendfile        on;
      keepalive_timeout  65;
      upstream portal {
          # 下面填入A主机IP及应用服务端口
          server X.X.X.X:X;      
          # 下面填入B主机IP及应用服务端口
          #server X.X.X.X:X;      #B节点下线
      }
      upstream portal_test {
          # 下面填入A主机IP及应用服务端口
          server X.X.X.X:X;
          # 下面填入B主机IP及应用服务端口
          server X.X.X.X:X;
      }
      
      server {
          listen       XXX;#填入Nginx端口
          server_name  localhost;
          
          location / {
              set $backend portal;
              set $test portal_test;
              #下面填入灰度验证机器IP
              #if ( $remote_addr ~* "X.X.X.X") {
              #    set $backend $test;
              #}
              proxy_pass https://$backend;
          }
          error_page   500 502 503 504  /50x.html;
          location = /50x.html {
              root   html;
          }
     }
  }
  ```
  
- **B边节点灰度上线-代码示例**
  ```
  worker_processes  1;
  events {
      worker_connections  1024;
  }
  http {
      include       mime.types;
      default_type  application/octet-stream;
      log_format main  '$time_local|$remote_addr[$remote_port]|$request|$request_method|$content_length|'
          '$content_type|$http_referer|$host|$http_x_forwarded_for|'
          '$http_true_client_ip|$server_name|$request_uri|$server_addr|$server_port|'
          '$status|$request_time|$upstream_addr|$upstream_response_time|$cookie_domain_tag';
      access_log logs/access.log main; #访问日志：存放路径，日志级别。
      error_log logs/error.log; #错误日志：存放路径。
      sendfile        on;
      keepalive_timeout  65;
      upstream portal {
          # 下面填入A主机IP及应用服务端口
          server X.X.X.X:X;      
          # 下面填入B主机IP及应用服务端口
          #server X.X.X.X:X;      #B节点下线
      }
      upstream portal_test {
          # 下面填入A主机IP及应用服务端口
          #server X.X.X.X:X;
          # 下面填入B主机IP及应用服务端口
          server X.X.X.X:X;       #B节点灰度上线
      }
      
      server {
          listen       XXX;#填入Nginx端口
          server_name  localhost;
          
          location / {
              set $backend portal;
              set $test portal_test;
              #下面填入灰度验证机器IP
              if ( $remote_addr ~* "X.X.X.X") {
                  set $backend $test;
              }
              proxy_pass https://$backend;
          }
          error_page   500 502 503 504  /50x.html;
          location = /50x.html {
              root   html;
          }
     }
  }
  ```
  
- **节点上线-代码示例**
  ```
  worker_processes  1;
  events {
      worker_connections  1024;
  }
  http {
      include       mime.types;
      default_type  application/octet-stream;
      log_format main  '$time_local|$remote_addr[$remote_port]|$request|$request_method|$content_length|'
          '$content_type|$http_referer|$host|$http_x_forwarded_for|'
          '$http_true_client_ip|$server_name|$request_uri|$server_addr|$server_port|'
          '$status|$request_time|$upstream_addr|$upstream_response_time|$cookie_domain_tag';
      access_log logs/access.log main; #访问日志：存放路径，日志级别。
      error_log logs/error.log; #错误日志：存放路径。
      sendfile        on;
      keepalive_timeout  65;
      upstream portal {
          # 下面填入A主机IP及应用服务端口
          server X.X.X.X:X;      
          # 下面填入B主机IP及应用服务端口
          server X.X.X.X:X;
      }
      upstream portal_test {
          # 下面填入A主机IP及应用服务端口
          server X.X.X.X:X;
          # 下面填入B主机IP及应用服务端口
          server X.X.X.X:X;
      }
      
      server {
          listen       XXX;#填入Nginx端口
          server_name  localhost;
          
          location / {
              set $backend portal;
              set $test portal_test;
              #下面填入灰度验证机器IP
              #if ( $remote_addr ~* "X.X.X.X") {
              #    set $backend $test;
              #}
              proxy_pass https://$backend;
          }
          error_page   500 502 503 504  /50x.html;
          location = /50x.html {
              root   html;
          }
     }
  }
  ```
  
 
