Files
asd-backend/docs/BLUE-GREEN-DEPLOY.md
2026-07-13 18:30:38 +08:00

245 lines
6.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.
# 蓝绿部署(新服务器)
> **服务器**47.109.203.92 (Aliyun, Debian 13)
> **nginx**:原生 nginx非 Docker/OpenResty
> **PostgreSQL**Docker 容器 `postgres:17.6-alpine`
> **部署用户**`deploy`(有 sudo 权限)
## 域名与环境映射
```
域名 环境 后端端口 数据库
────────────────────────────────────────────────────
dev.xmclassmate.top 开发/测试 :8080 milkydata_dev
xmclassmate.top 生产 :4433 / :4434 milkydata
```
> **原则**:两个域名永远指向各自的环境,不互换。生产采用蓝绿部署实现零停机。
## 当前问题
单实例部署时存在停机时间:
```
停止服务 → 上传新代码 → 重启服务 → 跑迁移
3-5 秒停机
```
## 开发环境dev.xmclassmate.top
保持单实例,无需蓝绿:
```
dev.xmclassmate.top
nginx → :8080单实例
milkydata_dev
```
开发环境不需要蓝绿的原因:
| 原因 | 说明 |
|------|------|
| 停机时间可接受 | 仅开发者使用,重启 3-5 秒无影响 |
| 简化运维 | 少维护一套 systemd service |
| 快速迭代 | 直接 `deploy.sh development` 部署 |
## 生产环境xmclassmate.top— 蓝绿部署
### 架构
```
xmclassmate.top
nginx proxy直接路由
/ \
蓝色 :4433 绿色 :4434
(active) (idle)
\ /
milkydata共享
```
任何时候只有一个实例接收流量,另一个运行旧版本待命,切换零停机。
### 组件
**systemd service**
```
/etc/systemd/system/
├── rust-backend-blue.service ← :4433
└── rust-backend-green.service ← :4434
```
两个 service 的 `DATABASE_URL` 都指向 `milkydata`,仅端口不同。
**nginx proxy 配置:**
```
# /www/sites/xmclassmate.top/proxy/root.conf
location ^~ / {
proxy_pass https://127.0.0.1:4433; # deploy.sh 切换此端口
}
```
> 生产环境使用 HTTPS proxy`proxy_pass https://...`),因为后端自身处理 TLS。
切换时 `sed` 替换端口,`sudo nginx -s reload`
### 部署流程
```
初始:蓝色(:4433)=active 绿色(:4434)=idle
步骤 1部署到空闲环境绿色
① cargo build --release
② rsync 二进制 → 绿色目录
③ systemctl restart rust-backend-green.service
④ 运行数据库迁移
步骤 2验证绿色环境
curl http://127.0.0.1:4434/health
run_tests
步骤 3切换流量
sed 修改 proxy_pass → 127.0.0.1:4434
nginx -s reload
步骤 4验证
curl https://xmclassmate.top/health
结果:绿色(:4434)=active 蓝色(:4433)=idle
下次部署到蓝色
```
### 切换脚本
```bash
./scripts/switch-env.sh --switch green
# 或切回蓝色
./scripts/switch-env.sh --switch blue
# 查看当前状态
./scripts/switch-env.sh --status
```
### 回滚
```bash
./scripts/switch-env.sh --env prod --switch blue # 即时恢复旧版本
```
旧环境代码未变,无需重新部署。
## 数据库
| 环境 | 数据库 | 说明 |
|------|--------|------|
| 开发 | `milkydata_dev` | 单实例直连 |
| 生产 | `milkydata` | 蓝绿实例共享,名称不变 |
> 生产库 `milkydata`,开发库 `milkydata_dev`,两者独立。
## 限制与注意事项
### 1. 部署只能部署到非活动端口
每次部署必须部署到**当前空闲的环境**,绝不能直接部署到正在接收流量的端口。
```
正确流程:
Green(:4434) 活动中 → 部署到 Blue(:4433) → 测试 → 切到 Blue(:4433)
Blue(:4433) 活动中 → 部署到 Green(:4434) → 测试 → 切到 Green(:4434)
错误:
Green(:4434) 活动中 → 直接部署到 Green(:4434) ← ❌ 会产生停机
```
**原因**:部署过程涉及服务重启(~3-5 秒),如果直接部署到活动中环境,
会导致在此期间的用户请求失败。
### 2. 代码只能通过 deploy.sh 部署
禁止手动 `rsync` + `systemctl restart` 部署。必须使用统一脚本:
```bash
# 正确
./deploy.sh production --target blue --yes
# 错误
cargo build --release && rsync ... systemctl restart ← ❌
```
**原因**
- 自动备份旧版本,支持回滚
- 自动运行数据库迁移
- 自动验证服务健康
- 自动切换代理(零停机)
- 自动记录部署日志
- 跳过手动操作的遗漏风险
### 3. 部署后先验证再切换
`deploy.sh --skip-tests` 跳过了部署后的自动测试。建议仅在开发/快速迭代时使用,
生产环境应让测试跑完再切换。
### 4. 数据库兼容性(迁移注意事项)
蓝绿共享数据库,迁移需向前兼容:
| 迁移类型 | 兼容 | 说明 |
|---------|------|------|
| `CREATE TABLE` | ✅ | 新旧代码均可运行 |
| `ADD COLUMN` | ✅ | 需 `DEFAULT` 或允许 `NULL` |
| `RENAME COLUMN` | ❌ | 旧代码查询旧列名会失败 |
| `DROP COLUMN` | ❌ | 旧代码查询被删列会失败 |
不兼容的迁移需要三段式部署。
## 实施优先级
| 阶段 | 内容 | 工作量 |
|------|------|--------|
| P1 | 创建 blue + green 两个 systemd service | 小 |
| P2 | 编写 `deploy-blue-green.sh` + `switch-env.sh` | 中 |
| P3 | 实现 OpenResty proxy 配置切换 | 中 |
| P4 | 改造 `deploy.sh` 支持 `--blue-green` | 中 |
| P5 | 不兼容迁移的三段式部署文档 | 小 |
| P6 | 回滚文档 | 小 |
## 生产上线待办
| # | 步骤 | 说明 | 状态 |
|---|------|------|------|
| 1 | 数据迁移 | 已完成 | ✅ |
| 2 | 准备生产 service 文件 | 已完成 | ✅ |
| 3 | 部署新代码到 `:4433``:4434` | 已完成 | ✅ |
| 4 | `env.ts``CURRENT_ENV = 'production'` | 已完成 | ✅ |
| 5 | 微信开发者工具上传小程序 | 已完成 | ✅ |
| 6 | 确认 nginx `proxy_pass` 指向 :4433 | 已完成 | ✅ |
## 实施状态
蓝绿部署已实施并运行中:
| 组件 | 状态 |
|------|------|
| Blue service (:4433) | ✅ 运行中,当前活跃 |
| Green service (:4434) | ✅ 运行中,待命中 |
| `deploy.sh production --target blue/green` | ✅ 已支持 |
| `switch-env.sh --switch blue/green` | ✅ 自动切换 nginx proxy |
| nginx proxy | ✅ 指向活动中环境 |
### 下次部署流程
```bash
# 1. 查看当前活动中环境
./scripts/switch-env.sh --status
# 2. 部署到空闲环境(假设 green 活动中 → 部署到 blue
./deploy.sh production --target blue --yes
# 3. 部署完成后自动切换流量到 blue
# deploy.sh 自动调用 switch-env.sh --switch blue
```