Files
LabelChange-server/.trae/documents/zero_downtime_deployment_plan.md
2026-06-01 16:30:29 +08:00

6.9 KiB
Raw Blame History

.NET Core 无停机部署解决方案计划

问题描述

当前后端程序CONTROLLER.exe在需要更新时需要关闭EXE程序再启动这导致在更新期间客户端无法访问服务。

解决方案概述

实现一个无停机部署Zero Downtime Deployment系统通过以下关键组件

  1. 蓝绿部署:同时运行两个版本的应用程序
  2. 反向代理使用IIS或Nginx进行流量转发
  3. 健康检查:确保只有健康的实例才接收流量
  4. 优雅关闭:确保正在处理的请求完成后再关闭应用

实现步骤

第一阶段:部署基础设施准备

1.1 创建部署目录结构

D:\EPproject\LabelReplaceServer\
├── deployment/
│   ├── blue/          (蓝实例目录)
│   ├── green/         (绿实例目录)
│   ├── scripts/       (部署脚本)
│   └── config/        (配置文件)
├── src/               (源代码)
├── publish/           (发布包)
└── docs/

1.2 配置应用程序级别

  • 创建端口配置文件允许蓝绿实例使用不同端口如5000和5001
  • 修改Program.cs:支持从环境变量读取端口号
  • 创建健康检查端点GET /health 返回应用健康状态

1.3 配置反向代理

  • 选择反向代理方案
    • 选项A使用IIS Application Request Routing (ARR)
    • 选项B使用Nginx
    • 选项C使用.NET Reverse ProxyYARP库
  • 配置流量路由规则
  • 设置故障转移策略

第二阶段:代码修改

2.1 修改Program.cs支持端口配置

  • 从环境变量或启动参数读取端口号
  • 默认使用5000端口允许通过参数覆盖

2.2 添加健康检查端点

app.MapGet("/health", () => Results.Ok(new { status = "healthy", timestamp = DateTime.Now }));

2.3 添加优雅关闭支持

  • 实现ShutdownToken处理
  • 等待现有请求完成(超时时间可配置)
  • 记录关闭事件到日志

2.4 创建版本信息端点

app.MapGet("/api/version", () => Results.Ok(new { version = "1.0.0", buildTime = DateTime.Now }));

第三阶段:部署脚本创建

3.1 创建PowerShell部署脚本

  • build-and-publish.ps1:编译并发布应用
  • deploy-blue-green.ps1:执行蓝绿部署
  • health-check.ps1:检查实例健康状态
  • switch-traffic.ps1:切换流量到新实例
  • rollback.ps1:回滚到上一个版本

3.2 脚本功能详解

build-and-publish.ps1

  • 编译源代码:dotnet build -c Release
  • 发布应用:dotnet publish -c Release -o <output-dir>
  • 备份当前版本

deploy-blue-green.ps1

  • 确定当前活跃实例(蓝或绿)
  • 将新版本部署到非活跃实例
  • 启动新实例并验证健康状态
  • 切换反向代理指向新实例
  • 停止旧实例(可选保留)

health-check.ps1

  • 调用/health端点
  • 重试机制(指数退避)
  • 返回健康状态和时间戳

switch-traffic.ps1

  • 更新反向代理配置
  • 等待现有连接完成
  • 优雅关闭旧实例

第四阶段:反向代理配置

4.1 IIS配置推荐用于Windows

  • 配置Application Request Routing (ARR)
  • 创建服务器农场指向蓝绿实例
  • 配置健康探测规则
  • 设置故障转移和负载均衡

4.2 Nginx配置跨平台

upstream backend {
    server 127.0.0.1:5000 max_fails=2 fail_timeout=10s;
    server 127.0.0.1:5001 backup;
}

server {
    listen 80;
    location / {
        proxy_pass http://backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
    }
    
    location /health {
        proxy_pass http://backend;
    }
}

4.3 YARP配置.NET原生

  • 在反向代理项目中配置YARP
  • 定义集群配置(蓝绿实例)
  • 配置健康检查策略

第五阶段:自动化任务调度

5.1 创建Windows计划任务

  • 定期检查新版本可用性
  • 自动执行部署流程
  • 可选的维护窗口时间设置

5.2 日志和监控

  • 记录每次部署信息
  • 监控实例健康状态
  • 告警机制(可选)

第六阶段:测试和验证

6.1 单实例测试

  • 测试蓝实例正常运行
  • 测试绿实例正常运行
  • 测试切换过程

6.2 并发请求测试

  • 验证切换期间请求不丢失
  • 测试客户端重连机制
  • 验证会话保持

6.3 故障场景测试

  • 实例启动失败处理
  • 健康检查失败处理
  • 自动回滚场景

技术选择建议

推荐方案IIS + PowerShell脚本 + 蓝绿部署

优点

  • 充分利用Windows环境
  • 与.NET原生集成良好
  • 已在生产环境中验证

实现复杂度:中等

替代方案Nginx + PowerShell脚本

优点

  • 更轻量级
  • 跨平台支持
  • 配置简单

实现复杂度:中等

部署流程(执行时)

1. 用户运行: .\deploy-blue-green.ps1 -version "1.2.3"

2. 系统执行:
   ├─ 编译新版本
   ├─ 发布到非活跃实例目录(如./green/)
   ├─ 启动绿实例端口5001
   ├─ 健康检查直到绿实例就绪
   ├─ 更新反向代理配置(转向绿实例)
   ├─ 等待蓝实例连接优雅完成30秒超时
   ├─ 停止蓝实例
   └─ 记录成功日志

3. 客户端体验:
   - 部署期间服务始终可用
   - 可能存在极短时间的连接重置
   - 长连接需要实现客户端重连机制

回滚流程

1. 用户运行: .\rollback.ps1

2. 系统执行:
   ├─ 检查上一个版本
   ├─ 启动上一个版本实例
   ├─ 健康检查验证
   ├─ 切换反向代理指向
   ├─ 停止当前版本
   └─ 记录回滚日志

文件清单(需要创建/修改)

需要创建的文件:

  1. deployment/scripts/build-and-publish.ps1 - 编译发布脚本
  2. deployment/scripts/deploy-blue-green.ps1 - 部署脚本
  3. deployment/scripts/health-check.ps1 - 健康检查脚本
  4. deployment/scripts/switch-traffic.ps1 - 流量切换脚本
  5. deployment/scripts/rollback.ps1 - 回滚脚本
  6. deployment/scripts/stop-instance.ps1 - 停止实例脚本
  7. deployment/config/app-config.json - 应用配置模板
  8. deployment/config/iis-config.xmlnginx.conf - 反向代理配置

需要修改的文件:

  1. src/CONTROLLER/Program.cs - 支持端口配置、健康检查、优雅关闭
  2. src/CONTROLLER/appsettings.json - 添加部署相关配置

预期效果

优点

  • 部署时零停机
  • 快速回滚能力
  • 自动故障检测
  • 支持自动化部署

⚠️ 注意事项

  • 需要额外的服务器资源(运行两个实例)
  • 需要维护反向代理配置
  • 数据库迁移需要特殊处理
  • 客户端可能需要实现重连逻辑

实现优先级

  1. 必须修改Program.cs支持端口配置和健康检查
  2. 必须:创建基础部署脚本
  3. 必须:配置反向代理
  4. 应该:添加优雅关闭支持
  5. 可选:自动化任务调度和监控