Files
LabelChange-server/deployment/DEPLOYMENT_GUIDE.md
2026-06-01 16:30:29 +08:00

514 lines
12 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.

# 固定端口蓝绿部署完整指南
## 架构概述
本方案采用**固定端口蓝绿部署**策略,允许在不中断客户端访问的情况下更新应用程序:
```
网络流量 (Nginx)
→ 当前活跃实例 (蓝/绿) [端口固定: 5000 或 5001]
应用程序处理
```
### 关键特点
- **蓝实例**:固定运行在 **端口 5000**
- **绿实例**:固定运行在 **端口 5001**
- **零停机**Nginx始终指向活跃实例切换时无中断
- **快速回滚**:备份机制允许快速恢复
---
## 部署前准备
### 1. 目录结构创建
确保以下目录结构存在:
```
D:\EPproject\LabelReplaceServer\
├── deployment/
│ ├── blue/ # 蓝实例应用目录
│ ├── green/ # 绿实例应用目录
│ ├── backups/ # 备份目录
│ ├── logs/ # 部署日志目录
│ ├── scripts/ # 部署脚本目录
│ │ ├── build-and-publish.ps1
│ │ ├── health-check.ps1
│ │ ├── deploy-blue-green.ps1
│ │ ├── stop-instance.ps1
│ │ └── rollback.ps1
│ └── config/
│ └── deployment-config.json
├── src/
├── publish/
└── ...
```
### 2. 创建必要的目录
```powershell
mkdir D:\EPproject\LabelReplaceServer\deployment\blue
mkdir D:\EPproject\LabelReplaceServer\deployment\green
mkdir D:\EPproject\LabelReplaceServer\deployment\backups
mkdir D:\EPproject\LabelReplaceServer\deployment\logs
mkdir D:\EPproject\LabelReplaceServer\deployment\scripts
mkdir D:\EPproject\LabelReplaceServer\deployment\config
```
### 3. 配置Nginx反向代理
在你的Nginx配置文件中通常是 `nginx.conf`),按照以下方式配置:
```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;
server_name your-domain.com;
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 重要:设置连接超时
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
location /api/health {
proxy_pass http://backend;
access_log off;
}
}
```
**关键配置说明**
- `max_fails=2`在2次失败后标记服务器为down
- `fail_timeout=10s`故障超时10秒
- `backup`:指定备用服务器,平时不接收流量
---
## 部署流程
### 第一次初始化部署
**步骤1**:手动启动蓝实例
```powershell
# 在PowerShell中执行以下命令
# 编译发布到blue目录
D:\EPproject\LabelReplaceServer\deployment\scripts\build-and-publish.ps1 `
-OutputDirectory "D:\EPproject\LabelReplaceServer\deployment\blue" `
-Version "1.0.0"
# 手动启动蓝实例
cd D:\EPproject\LabelReplaceServer\deployment\blue
$env:DEPLOYMENT_INSTANCE = "blue"
$env:SHUTDOWN_TIMEOUT = "30"
.\CONTROLLER.exe
```
**步骤2**:验证蓝实例运行
```powershell
# 在另一个PowerShell终端中
curl http://localhost:5000/api/health
# 应该返回:
# {
# "status": "healthy",
# "instance": "blue",
# "port": 5000,
# ...
# }
```
**步骤3**:初始化部署状态
```powershell
# 创建初始状态文件
$state = @{
activeInstance = "blue"
lastUpdate = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
version = "1.0.0"
}
$state | ConvertTo-Json |
Set-Content -Path "D:\EPproject\LabelReplaceServer\deployment\instance_state.json" -Force
```
**步骤4**更新Nginx配置
修改Nginx配置让主服务器指向蓝实例5000备用指向绿实例5001
### 后续部署流程(核心部署脚本)
一旦初始化完成,所有后续部署都通过以下命令执行:
```powershell
# 执行蓝绿部署(自动选择非活跃实例)
D:\EPproject\LabelReplaceServer\deployment\scripts\deploy-blue-green.ps1 `
-Version "1.1.0"
# 或指定目标实例
D:\EPproject\LabelReplaceServer\deployment\scripts\deploy-blue-green.ps1 `
-Version "1.1.0" `
-TargetInstance "green"
```
**部署脚本执行流程**
```
1. 确定当前活跃实例(读取 instance_state.json
├─ 若为 blue → 部署到 green
├─ 若为 green → 部署到 blue
2. 编译新版本到非活跃实例
├─ 执行 dotnet clean/restore/build/publish
├─ 保存当前版本为备份
3. 启动新实例
├─ 设置环境变量 DEPLOYMENT_INSTANCE=green/blue
├─ 启动 CONTROLLER.exe
4. 健康检查最多30次重试每次间隔1秒
├─ 调用 /api/health 端点
├─ 若成功 → 继续
├─ 若失败 → 回滚并退出
5. 切换流量更新Nginx配置或DNS
├─ 更新 instance_state.json
├─ Nginx自动切换到新实例
6. 优雅关闭旧实例
├─ 等待旧实例完成当前请求最多30秒
├─ 停止旧实例进程
7. 记录日志
├─ 保存到 deployment/logs/deployment.log
```
**部署中发生了什么?**
| 时间 | 操作 | 客户端体验 |
|------|------|---------|
| T=0s | 新实例启动中 | 请求转发到蓝/绿 ✓ |
| T=2s | 健康检查中 | 请求转发到蓝/绿 ✓ |
| T=5s | 状态更新 | 可能短暂延迟(<1s |
| T=7s | 旧实例关闭 | 新请求转发到新实例 |
---
## 环境变量
### 部署实例标识
启动应用时需要设置环境变量标识实例
```powershell
# 蓝实例
$env:DEPLOYMENT_INSTANCE = "blue"
$env:SHUTDOWN_TIMEOUT = "30"
.\CONTROLLER.exe
# 或
# 绿实例
$env:DEPLOYMENT_INSTANCE = "green"
$env:SHUTDOWN_TIMEOUT = "30"
.\CONTROLLER.exe
```
### 环境变量说明
| 变量名 | 说明 | 默认值 | 用途 |
|--------|------|--------|------|
| `DEPLOYMENT_INSTANCE` | 实例标识 | "blue" | 决定使用的端口blue=5000, green=5001 |
| `SHUTDOWN_TIMEOUT` | 优雅关闭超时 | "30" | 秒数等待现有请求完成的最长时间 |
| `ASPNETCORE_ENVIRONMENT` | 环境 | "Production" | ASP.NET Core 环境配置 |
---
## 健康检查端点
### `/api/health` 端点
**请求**
```
GET /api/health
```
**响应 (200 OK)**
```json
{
"status": "healthy",
"instance": "blue",
"port": 5000,
"timestamp": "2026-05-15T10:30:45Z",
"uptime": "2026-05-15T10:15:30Z",
"environment": "Production"
}
```
### `/api/version` 端点
**请求**
```
GET /api/version
```
**响应**
```json
{
"version": "1.0.0",
"instance": "blue",
"port": 5000,
"buildTime": "2026-05-15T10:15:30Z",
"timestamp": "2026-05-15T10:30:45Z"
}
```
---
## 回滚流程
### 发生故障时快速回滚
```powershell
# 执行回滚脚本
D:\EPproject\LabelReplaceServer\deployment\scripts\rollback.ps1
```
**回滚流程**
```
1. 读取当前活跃实例
2. 停止当前实例
3. 从最新备份恢复文件
4. 启动恢复的实例
5. 健康检查验证
6. 更新状态文件
7. Nginx自动切换回旧端口
```
**预期结果**
```
前状态green (新版本) 活跃
回滚后blue (旧版本) 活跃
客户端流量自动转向 blue端口 5000
```
---
## 监控和日志
### 日志位置
所有部署日志记录在
```
D:\EPproject\LabelReplaceServer\deployment\logs\deployment.log
```
### 日志内容示例
```
[2026-05-15 10:30:45] [INFO] [BluGreen] ========================================
[2026-05-15 10:30:45] [INFO] [BluGreen] 蓝绿部署流程开始
[2026-05-15 10:30:45] [INFO] [BluGreen] 版本: 1.1.0
[2026-05-15 10:30:45] [INFO] [BluGreen] 已加载部署配置
[2026-05-15 10:30:45] [INFO] [BluGreen] 当前活跃实例: blue
[2026-05-15 10:30:45] [INFO] [BluGreen] 下一个部署实例: green
[2026-05-15 10:35:12] [INFO] [BluGreen] 健康检查通过
[2026-05-15 10:35:13] [INFO] [BluGreen] 已更新活跃实例为: green (版本: 1.1.0)
[2026-05-15 10:35:15] [INFO] [BluGreen] 蓝绿部署完成!
```
### 实例状态文件
```
D:\EPproject\LabelReplaceServer\deployment\instance_state.json
```
**内容示例**
```json
{
"activeInstance": "green",
"lastUpdate": "2026-05-15 10:35:15",
"version": "1.1.0"
}
```
---
## 故障排查
### 问题1新实例健康检查失败
**症状**部署中止显示"新实例健康检查失败"
**排查步骤**
```powershell
# 1. 检查应用是否启动
Get-Process CONTROLLER
# 2. 手动测试健康检查
curl http://localhost:5000/api/health
curl http://localhost:5001/api/health
# 3. 查看部署日志
Get-Content "D:\EPproject\LabelReplaceServer\deployment\logs\deployment.log" -Tail 50
# 4. 检查应用日志
Get-Content "D:\EPproject\LabelReplaceServer\deployment\logs\api_log-*.txt" -Tail 50
```
### 问题2旧实例无法停止
**症状**部署完成但旧实例仍在运行
**解决方案**
```powershell
# 强制停止所有 CONTROLLER 进程
Get-Process CONTROLLER | Stop-Process -Force
# 等待2秒后验证
Start-Sleep -Seconds 2
Get-Process CONTROLLER -ErrorAction SilentlyContinue
```
### 问题3Nginx未切换流量
**症状**切换后客户端仍连接到旧实例
**排查步骤**
```
1. 确认 instance_state.json 已更新
- 检查 activeInstance 字段是否变更
2. 检查 Nginx 配置
- 确保上游地址正确
- 重新加载 Nginx: nginx -s reload
3. 清除DNS缓存如适用
- ipconfig /flushdns
4. 检查客户端连接
- 新连接应转向新实例
- 已建立连接可能保持不变
```
---
## 最佳实践
### 1. **选择合适的部署时间**
- 避免业务高峰期
- 选择流量较少的时间窗口
- 建议凌晨或夜间部署
### 2. **监控部署过程**
- 打开日志文件实时查看
- 监控两个端口的流量
- 部署后进行功能验证
### 3. **备份管理**
- 定期清理旧备份保留最近5个版本
- 备份目录空间充足
- 测试备份可恢复性
### 4. **健康检查优化**
```powershell
# 手动测试健康检查响应时间
Measure-Command {
curl http://localhost:5000/api/health
}
```
### 5. **客户端重连机制**
- 建议客户端实现自动重连
- 设置合理的重试次数3-5次
- 指数退避策略
---
## 快速参考命令
```powershell
# 查看当前活跃实例
Get-Content "D:\EPproject\LabelReplaceServer\deployment\instance_state.json" | ConvertFrom-Json
# 查看部署日志最近50行
Get-Content "D:\EPproject\LabelReplaceServer\deployment\logs\deployment.log" -Tail 50
# 测试蓝实例
curl http://localhost:5000/api/health
# 测试绿实例
curl http://localhost:5001/api/health
# 查看CONTROLLER进程
Get-Process CONTROLLER
# 部署新版本
& "D:\EPproject\LabelReplaceServer\deployment\scripts\deploy-blue-green.ps1" -Version "1.2.0"
# 回滚到上一个版本
& "D:\EPproject\LabelReplaceServer\deployment\scripts\rollback.ps1"
# 停止应用
Get-Process CONTROLLER | Stop-Process -Force
```
---
## 常见问题 (FAQ)
**Q: 为什么要用固定端口而不是动态端口?**
A: 固定端口更简单且不需要Nginx权限更改部署脚本也更简洁Nginx配置一次后无需修改
**Q: 部署期间客户端会断线吗?**
A: 新连接会自动转向新实例已建立的长连接会保持到旧实例直到超时或主动关闭
**Q: 回滚需要多长时间?**
A: 通常2-5分钟取决于实例启动时间和健康检查通过速度
**Q: 可以同时运行两个实例吗?**
A: 可以但同一时间只有一个实例作为"活跃实例"接收流量另一个是备用
**Q: 如何验证部署成功?**
A:
1. 检查 instance_state.json确认 activeInstance 已变更
2. 调用 /api/version 确认返回新版本号
3. 检查部署日志最后一行应显示"蓝绿部署完成"
---
## 总结
这个固定端口蓝绿部署方案提供了
- **零停机部署**业务连续性有保障
- **快速回滚**问题发生时可秒级回滚
- **简单配置**固定端口Nginx配置一次即可
- **自动化**PowerShell脚本全程自动化
- **完整日志**所有操作都有详细日志记录
祝你部署顺利!🚀