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

250 lines
6.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# .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 添加健康检查端点
```csharp
app.MapGet("/health", () => Results.Ok(new { status = "healthy", timestamp = DateTime.Now }));
```
#### 2.3 添加优雅关闭支持
- 实现ShutdownToken处理
- 等待现有请求完成(超时时间可配置)
- 记录关闭事件到日志
#### 2.4 创建版本信息端点
```csharp
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配置跨平台
```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.xml``nginx.conf` - 反向代理配置
### 需要修改的文件:
1. `src/CONTROLLER/Program.cs` - 支持端口配置、健康检查、优雅关闭
2. `src/CONTROLLER/appsettings.json` - 添加部署相关配置
## 预期效果
**优点**
- 部署时零停机
- 快速回滚能力
- 自动故障检测
- 支持自动化部署
⚠️ **注意事项**
- 需要额外的服务器资源(运行两个实例)
- 需要维护反向代理配置
- 数据库迁移需要特殊处理
- 客户端可能需要实现重连逻辑
## 实现优先级
1. **必须**修改Program.cs支持端口配置和健康检查
2. **必须**:创建基础部署脚本
3. **必须**:配置反向代理
4. **应该**:添加优雅关闭支持
5. **可选**:自动化任务调度和监控