Files
asd-backend/docs/BLUE-GREEN-DEPLOY.md

169 lines
4.5 KiB
Markdown
Raw 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.
# 蓝绿部署计划
## 当前问题
```
部署时: 停止服务 → 上传新代码 → 重启服务 → 跑迁移
此时有停机时间(约 3-5 秒)
```
单实例部署的风险部署期间用户请求失败502/503
## 蓝绿部署架构
```
OpenResty反向代理
/ \
蓝色环境 绿色环境
127.0.0.1:8081 127.0.0.1:8082
rust-backend-blue rust-backend-green
| |
↓ ↓
同一个 PostgreSQLmilkydata_dev
```
两个环境共享同一个数据库,但运行不同的代码版本。任何时候只有一个环境接收流量,另一个空闲。
## 组件变更
### 新增 systemd service
```
/etc/systemd/system/
├── rust-backend-blue.service ← 端口 8081
└── rust-backend-green.service ← 端口 8082
```
每个 service 文件与现有的 `rust-backend-dev.service` 结构一致,仅端口和描述不同。
### 新增 OpenResty 配置
```
# /www/sites/dev.xmclassmate.top/proxy/active-backend.conf
# 由 deploy.sh 自动切换
# 蓝色环境
location ^~ / {
proxy_pass http://127.0.0.1:8081;
...
}
```
切换时只需替换这个文件中的端口号,然后 `nginx -s reload`
### 新增脚本
```
scripts/
├── deploy-blue-green.sh ← 蓝绿部署主脚本
└── switch-blue-green.sh ← 手动切换蓝绿
```
## 部署流程
```
部署前: 蓝色=active(:8081) 绿色=idle(:8082)
步骤 1部署到空闲环境绿色
cargo build --release
rsync 二进制 → 绿色目录
systemctl restart rust-backend-green.service
run_migrations
步骤 2验证绿色环境
curl http://127.0.0.1:8082/health
run_tests
步骤 3切换流量
修改 OpenResty proxy_pass → 127.0.0.1:8082
nginx -s reload
步骤 4验证切换后
curl https://dev.xmclassmate.top/health
部署后: 绿色=active(:8082) 蓝色=idle(:8081)
← 下次部署时部署到蓝色
```
## 切换脚本
`switch-blue-green.sh` 手动切换活动环境:
```bash
# 查看当前活动环境
./switch-blue-green.sh --status
# → 当前活动: 蓝色 (127.0.0.1:8081)
# 切换到绿色
./switch-blue-green.sh --switch green
# → 修改 proxy_pass → 127.0.0.1:8082
# → nginx -s reload
# → 验证健康检查
# → 切换成功
```
## deploy.sh 改造
现有 `deploy.sh` 增加 `--blue-green` 模式:
```bash
./deploy.sh development --blue-green
```
自动检测空闲环境并部署到该环境:
```
1. 检查 8081 和 8082 哪个是空闲的
2. 启动空闲环境的新版本
3. 测试新版本
4. 切换流量
5. 停止旧版本
```
## 数据库迁移注意事项
蓝绿部署中数据库是共享的,迁移需要考虑**向前兼容**
| 迁移类型 | 是否兼容 | 说明 |
|---------|---------|------|
| `CREATE TABLE` | ✅ 安全 | 新旧代码都能运行 |
| `ADD COLUMN` | ✅ 安全(需 DEFAULT 或 NULL | 旧代码忽略新列 |
| `RENAME COLUMN` | ❌ **不兼容** | 旧代码查询旧列名会失败 |
| `DROP COLUMN` | ❌ 不兼容 | 旧代码查询被删列会失败 |
对于不兼容的迁移(如列重命名 `010_rename_paid_fields.sql`),需要:
```
1. 先部署兼容旧列名的新代码(两个列名都支持)
2. 再执行迁移重命名列
3. 最后部署只支持新列名的代码
```
这称为**三段式迁移**,需要代码层面同时兼容新旧列名。当前 `010` 迁移不符合蓝绿条件,需要在代码中添加兼容层后再启用蓝绿。
## 实施步骤
| 阶段 | 内容 | 工作量 |
|------|------|--------|
| P1 | 创建两个 systemd service 文件blue + green | 小 |
| P2 | 编写 `deploy-blue-green.sh``switch-blue-green.sh` | 中 |
| P3 | 编写 OpenResty 配置切换逻辑1Panel API 或 直接改文件) | 中 |
| P4 | 改造现有 `deploy.sh` 支持 `--blue-green` | 中 |
| P5 | 处理不兼容迁移(列重命名等)的三段式部署 | 大 |
| P6 | 编写文档和回滚流程 | 小 |
## 回滚流程
```bash
# 如果新环境有问题,立即切回旧环境
./switch-blue-green.sh --switch blue
# 旧环境仍然是部署前的版本,无需重新部署
# 修复问题后重新走蓝绿部署流程
```
## 建议
**当前项目规模(~100 日活)不需要蓝绿部署**。停机 3-5 秒的影响可以忽略。但如果是为了学习目的或为未来增长做准备,可以按 P1→P2 的顺序逐步实现。