docs: 更新蓝绿部署文档-域名固定映射+新增待办状态
This commit is contained in:
@@ -1,227 +1,171 @@
|
|||||||
# 蓝绿部署计划
|
# 蓝绿部署计划
|
||||||
|
|
||||||
|
## 域名与环境映射
|
||||||
|
|
||||||
|
```
|
||||||
|
域名 环境 后端端口 数据库
|
||||||
|
────────────────────────────────────────────────────
|
||||||
|
dev.xmclassmate.top 开发/测试 :8080 milkydata_dev
|
||||||
|
xmclassmate.top 生产 :4433 / :4434 milkydata_dev
|
||||||
|
```
|
||||||
|
|
||||||
|
> **原则**:两个域名永远指向各自的环境,不互换。生产采用蓝绿部署实现零停机。
|
||||||
|
|
||||||
## 当前问题
|
## 当前问题
|
||||||
|
|
||||||
```
|
单实例部署时存在停机时间:
|
||||||
部署时: 停止服务 → 上传新代码 → 重启服务 → 跑迁移
|
|
||||||
↑
|
|
||||||
此时有停机时间(约 3-5 秒)
|
|
||||||
```
|
|
||||||
|
|
||||||
单实例部署的风险:部署期间用户请求失败(502/503)。
|
|
||||||
|
|
||||||
## 概念澄清
|
|
||||||
|
|
||||||
蓝绿部署仅用于**生产环境**,开发环境保持单实例:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
开发环境(dev.xmclassmate.top) — 单实例,无需蓝绿
|
停止服务 → 上传新代码 → 重启服务 → 跑迁移
|
||||||
└── 实例 :8080
|
↑
|
||||||
└── 数据库 milkydata_dev(当前与生产共用)
|
3-5 秒停机
|
||||||
|
|
||||||
生产环境(xmclassmate.top) — 蓝绿部署
|
|
||||||
├── 蓝色实例 :4433(当前活动)
|
|
||||||
├── 绿色实例 :4434(空闲)
|
|
||||||
└── 数据库 milkydata_dev(蓝绿共享,名称不变)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
> **当前状态**:生产环境使用 `milkydata_dev` 数据库(数据已从 `milkydata` 迁移)。开发与生产暂共用同一数据库,后续建议拆分。
|
## 开发环境(dev.xmclassmate.top)
|
||||||
|
|
||||||
|
保持单实例,无需蓝绿:
|
||||||
|
|
||||||
|
```
|
||||||
|
dev.xmclassmate.top
|
||||||
|
│
|
||||||
|
OpenResty → :8080(单实例)
|
||||||
|
│
|
||||||
|
milkydata_dev
|
||||||
|
```
|
||||||
|
|
||||||
开发环境不需要蓝绿的原因:
|
开发环境不需要蓝绿的原因:
|
||||||
|
|
||||||
| 原因 | 说明 |
|
| 原因 | 说明 |
|
||||||
|------|------|
|
|------|------|
|
||||||
| 停机时间可接受 | 开发环境只有开发者使用,重启 3-5 秒无影响 |
|
| 停机时间可接受 | 仅开发者使用,重启 3-5 秒无影响 |
|
||||||
| 简化运维 | 少维护一套 systemd service 和 nginx 配置 |
|
| 简化运维 | 少维护一套 systemd service |
|
||||||
| 快速迭代 | 直接 `deploy.sh development` 部署即可,无需切换步骤 |
|
| 快速迭代 | 直接 `deploy.sh development` 部署 |
|
||||||
|
|
||||||
生产环境使用蓝绿部署实现零停机发布。
|
## 生产环境(xmclassmate.top)— 蓝绿部署
|
||||||
|
|
||||||
### 数据库与蓝绿的关系
|
### 架构
|
||||||
|
|
||||||
数据库名称**不受蓝绿切换影响**:
|
|
||||||
|
|
||||||
| 环境 | 数据库 | 蓝绿实例共同连接 |
|
|
||||||
|------|--------|----------------|
|
|
||||||
| 开发 | `milkydata_dev` | 单实例,无需蓝绿 |
|
|
||||||
| 生产 | `milkydata_dev` | `DATABASE_URL=postgres://.../milkydata_dev` |
|
|
||||||
|
|
||||||
两个蓝绿实例的 service 文件中 `DATABASE_URL` 配置为完全相同的值。切换蓝绿时只改端口,不改数据库连接。
|
|
||||||
|
|
||||||
## 域名与蓝绿的关系
|
|
||||||
|
|
||||||
蓝绿部署**不改变域名访问方式**,域名始终指向同一 OpenResty 实例:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
用户访问 OpenResty(域名不变) 后端实例
|
xmclassmate.top
|
||||||
xmclassmate.top ──→ xmclassmate.top ──→ :4433(蓝)或 :4434(绿)
|
│
|
||||||
|
OpenResty proxy
|
||||||
|
/ \
|
||||||
|
蓝色 :4433 绿色 :4434
|
||||||
|
(active) (idle)
|
||||||
|
\ /
|
||||||
|
milkydata_dev(共享)
|
||||||
```
|
```
|
||||||
|
|
||||||
切换时 OpenResty 内部的 `proxy_pass` 指向的目标端口变更,**用户无感知**:
|
任何时候只有一个实例接收流量,另一个运行旧版本待命,切换零停机。
|
||||||
|
|
||||||
```
|
### 组件
|
||||||
切换前:xmclassmate.top ──→ proxy_pass 127.0.0.1:4433 ← 蓝色活动
|
|
||||||
切换后:xmclassmate.top ──→ proxy_pass 127.0.0.1:4434 ← 绿色活动
|
|
||||||
```
|
|
||||||
|
|
||||||
小程序前端的 `env.ts` 中 `CURRENT_ENV=production` 指向 `xmclassmate.top`,蓝绿切换时**无需修改**。
|
**systemd service:**
|
||||||
|
|
||||||
## 蓝绿部署架构(生产环境)
|
|
||||||
|
|
||||||
```
|
|
||||||
xmclassmate.top
|
|
||||||
│
|
|
||||||
OpenResty proxy
|
|
||||||
/ \
|
|
||||||
蓝色 (:4433 active) 绿色 (:4434 idle)
|
|
||||||
rust-backend-blue rust-backend-green
|
|
||||||
│ │
|
|
||||||
└──────────┬─────────────┘
|
|
||||||
↓
|
|
||||||
milkydata_dev(共享数据库)
|
|
||||||
```
|
|
||||||
|
|
||||||
任何时候只有一个实例接收流量,另一个运行旧版本待命。
|
|
||||||
|
|
||||||
## 组件变更
|
|
||||||
|
|
||||||
### 新增 systemd service(生产环境)
|
|
||||||
|
|
||||||
```
|
```
|
||||||
/etc/systemd/system/
|
/etc/systemd/system/
|
||||||
├── rust-backend-blue.service ← 端口 4433
|
├── rust-backend-blue.service ← :4433
|
||||||
└── rust-backend-green.service ← 端口 4434
|
└── rust-backend-green.service ← :4434
|
||||||
```
|
```
|
||||||
|
|
||||||
每个 service 配置一致,仅端口和描述不同,`DATABASE_URL` 均指向 `milkydata_dev`。
|
两个 service 的 `DATABASE_URL` 都指向 `milkydata_dev`,仅端口不同。
|
||||||
|
|
||||||
### 新增 OpenResty 配置
|
**OpenResty proxy 配置:**
|
||||||
|
|
||||||
由 1Panel 管理的 proxy 配置:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
# /www/sites/xmclassmate.top/proxy/active-backend.conf
|
# /www/sites/xmclassmate.top/proxy/root.conf
|
||||||
|
|
||||||
location ^~ / {
|
location ^~ / {
|
||||||
proxy_pass http://127.0.0.1:4433; # ← deploy.sh 切换此端口
|
proxy_pass http://127.0.0.1:4433; # deploy.sh 切换此端口
|
||||||
...
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
切换时 `sed` 替换端口号,然后 `nginx -s reload`。
|
切换时 `sed` 替换端口,`nginx -s reload`。
|
||||||
|
|
||||||
### 新增脚本
|
### 部署流程
|
||||||
|
|
||||||
```
|
```
|
||||||
scripts/
|
初始:蓝色(:4433)=active 绿色(:4434)=idle
|
||||||
├── deploy-blue-green.sh ← 蓝绿部署主脚本
|
|
||||||
└── switch-env.sh ← 手动切换/查看状态
|
|
||||||
```
|
|
||||||
|
|
||||||
## 部署流程(生产环境)
|
|
||||||
|
|
||||||
```
|
|
||||||
初始状态:蓝色(:4433)=active 绿色(:4434)=idle
|
|
||||||
|
|
||||||
步骤 1:部署到空闲环境(绿色)
|
步骤 1:部署到空闲环境(绿色)
|
||||||
① 编译新代码
|
① cargo build --release
|
||||||
② 上传二进制到绿色目录
|
② rsync 二进制 → 绿色目录
|
||||||
③ systemctl restart rust-backend-green.service
|
③ systemctl restart rust-backend-green.service
|
||||||
④ 运行数据库迁移
|
④ 运行数据库迁移
|
||||||
|
|
||||||
步骤 2:验证绿色环境
|
步骤 2:验证绿色环境
|
||||||
curl http://127.0.0.1:4434/health
|
curl http://127.0.0.1:4434/health
|
||||||
运行 9 项部署测试
|
run_tests
|
||||||
|
|
||||||
步骤 3:切换流量
|
步骤 3:切换流量
|
||||||
sed 修改 OpenResty proxy_pass → 127.0.0.1:4434
|
sed 修改 proxy_pass → 127.0.0.1:4434
|
||||||
nginx -s reload
|
nginx -s reload
|
||||||
|
|
||||||
步骤 4:验证切换后
|
步骤 4:验证
|
||||||
curl https://xmclassmate.top/health
|
curl https://xmclassmate.top/health
|
||||||
|
|
||||||
结果:绿色(:4434)=active 蓝色(:4433)=idle
|
结果:绿色(:4434)=active 蓝色(:4433)=idle
|
||||||
下次部署时部署到蓝色
|
下次部署到蓝色
|
||||||
```
|
```
|
||||||
|
|
||||||
## 切换脚本
|
### 切换脚本
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 查看当前活动环境
|
|
||||||
./scripts/switch-env.sh --status
|
|
||||||
# → 生产环境: 蓝色 (127.0.0.1:4433)
|
|
||||||
|
|
||||||
# 切换到绿色
|
|
||||||
./scripts/switch-env.sh --env prod --switch green
|
./scripts/switch-env.sh --env prod --switch green
|
||||||
# → 修改 proxy_pass 127.0.0.1:4434
|
# 或切回蓝色
|
||||||
# → nginx -s reload
|
./scripts/switch-env.sh --env prod --switch blue
|
||||||
# → 验证健康检查
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 数据库迁移注意事项
|
### 回滚
|
||||||
|
|
||||||
蓝绿部署中两个实例共享同一数据库(`milkydata_dev`),迁移脚本需要对**新旧两个版本的代码都兼容**:
|
```bash
|
||||||
|
./scripts/switch-env.sh --env prod --switch blue # 即时恢复旧版本
|
||||||
|
```
|
||||||
|
旧环境代码未变,无需重新部署。
|
||||||
|
|
||||||
| 迁移类型 | 兼容性 | 说明 |
|
## 数据库
|
||||||
|---------|--------|------|
|
|
||||||
| `CREATE TABLE` | ✅ | 新旧代码都能运行 |
|
| 环境 | 数据库 | 说明 |
|
||||||
|
|------|--------|------|
|
||||||
|
| 开发 | `milkydata_dev` | 单实例直连 |
|
||||||
|
| 生产 | `milkydata_dev` | 蓝绿实例共享,名称不变 |
|
||||||
|
|
||||||
|
> 当前开发与生产共用 `milkydata_dev`。后续建议拆分为 `milkydata_prod`。
|
||||||
|
|
||||||
|
## 迁移注意事项
|
||||||
|
|
||||||
|
蓝绿共享数据库,迁移需向前兼容:
|
||||||
|
|
||||||
|
| 迁移类型 | 兼容 | 说明 |
|
||||||
|
|---------|------|------|
|
||||||
|
| `CREATE TABLE` | ✅ | 新旧代码均可运行 |
|
||||||
| `ADD COLUMN` | ✅ | 需 `DEFAULT` 或允许 `NULL` |
|
| `ADD COLUMN` | ✅ | 需 `DEFAULT` 或允许 `NULL` |
|
||||||
| `RENAME COLUMN` | ❌ | 旧代码仍查旧列名 |
|
| `RENAME COLUMN` | ❌ | 旧代码查询旧列名会失败 |
|
||||||
| `DROP COLUMN` | ❌ | 旧代码查询被删列 |
|
| `DROP COLUMN` | ❌ | 旧代码查询被删列会失败 |
|
||||||
|
|
||||||
对于不兼容的迁移(如列重命名),需要**三段式部署**:
|
不兼容的迁移需要三段式部署。
|
||||||
|
|
||||||
```
|
|
||||||
第 1 步:部署兼容双列名的代码(is_paid 和 is_member 同时支持)
|
|
||||||
第 2 步:执行迁移(重命名列)
|
|
||||||
第 3 步:部署只支持新列名的代码
|
|
||||||
```
|
|
||||||
|
|
||||||
当前代码已完成列重命名,若后续有类似变更需遵循此流程。
|
|
||||||
|
|
||||||
## 实施优先级
|
## 实施优先级
|
||||||
|
|
||||||
| 阶段 | 内容 | 工作量 |
|
| 阶段 | 内容 | 工作量 |
|
||||||
|------|------|--------|
|
|------|------|--------|
|
||||||
| P1 | 创建两个 systemd service 模板(blue + green) | 小 |
|
| P1 | 创建 blue + green 两个 systemd service | 小 |
|
||||||
| P2 | 编写 `deploy-blue-green.sh` + `switch-env.sh` | 中 |
|
| P2 | 编写 `deploy-blue-green.sh` + `switch-env.sh` | 中 |
|
||||||
| P3 | 实现 OpenResty proxy 配置切换 | 中 |
|
| P3 | 实现 OpenResty proxy 配置切换 | 中 |
|
||||||
| P4 | 改造 `deploy.sh` 支持 `--blue-green` | 中 |
|
| P4 | 改造 `deploy.sh` 支持 `--blue-green` | 中 |
|
||||||
| P5 | 处理不兼容迁移的三段式部署文档 | 小 |
|
| P5 | 不兼容迁移的三段式部署文档 | 小 |
|
||||||
| P6 | 编写回滚文档 | 小 |
|
| P6 | 回滚文档 | 小 |
|
||||||
|
|
||||||
## 回滚
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 新环境有问题 → 立即切回旧环境
|
|
||||||
./scripts/switch-env.sh --env prod --switch blue
|
|
||||||
|
|
||||||
# 旧环境代码未变,即时恢复
|
|
||||||
# 修复问题后重新部署到空闲环境
|
|
||||||
```
|
|
||||||
|
|
||||||
## 生产上线待办
|
## 生产上线待办
|
||||||
|
|
||||||
前端切换到生产域名前,需要依次完成以下步骤:
|
| # | 步骤 | 说明 | 状态 |
|
||||||
|
|---|------|------|------|
|
||||||
| # | 步骤 | 说明 | 执行方 |
|
| 1 | 数据迁移 `milkydata` → `milkydata_dev` | 已完成 | ✅ |
|
||||||
|---|------|------|--------|
|
| 2 | 准备生产 service 文件(填入实际密钥) | 待完成 | ⬜ |
|
||||||
| 1 | **数据迁移** | `milkydata` → `milkydata_dev`(**已完成**) | ✅ 已执行 |
|
| 3 | 部署新代码到 `:4433` | 待完成 | ⬜ |
|
||||||
| 2 | **准备生产 service 文件** | 填写 `deploy/rust-backend-prod.service` 中的实际值(JWT_SECRET、WECHAT_*、ALIPAY_*、DATABASE_URL) | 开发者 |
|
| 4 | `env.ts` 设 `CURRENT_ENV = 'production'` | 已完成 | ✅ |
|
||||||
| 3 | **部署生产后端** | `./deploy.sh production` 部署新代码到 `:4433`,数据库指向 `milkydata_dev` | 服务器操作 |
|
| 5 | 微信开发者工具上传小程序 | 待完成 | ⬜ |
|
||||||
| 4 | **修改前端 `CURRENT_ENV`** | `env.ts` 中 `CURRENT_ENV = 'production'` | 开发者 |
|
| 6 | 1Panel 确认 `proxy_pass` 指向 `:4433` | 待完成 | ⬜ |
|
||||||
| 5 | **上传小程序** | 微信开发者工具上传代码(此时连 `xmclassmate.top`) | 开发者 |
|
|
||||||
| 6 | **修改反向代理端口**(如需蓝绿) | 1Panel 中调整 `proxy_pass` 指向新端口 | 服务器操作 |
|
|
||||||
|
|
||||||
### 数据库配置汇总
|
|
||||||
|
|
||||||
| 环境 | 域名 | 数据库 | 当前端口 | 蓝绿备选端口 |
|
|
||||||
|------|------|--------|---------|-------------|
|
|
||||||
| 开发 | `dev.xmclassmate.top` | `milkydata_dev` | `:8080` | 无(单实例) |
|
|
||||||
| 生产 | `xmclassmate.top` | `milkydata_dev` | `:4433` | `:4434` |
|
|
||||||
|
|
||||||
> 生产与开发目前共用 `milkydata_dev`。`milkydata` 作为历史数据源保留,不再更新。后续建议创建独立的生产数据库 `milkydata_prod`。
|
|
||||||
|
|
||||||
## 当前是否实施
|
## 当前是否实施
|
||||||
|
|
||||||
当前项目规模(~100 日活),部署停机约 3-5 秒,实际影响可忽略。建议**保留文档**,当需要时再按 P1→P2 逐步实施。
|
当前暂未实施蓝绿。先实现 P1-P2 后启用。
|
||||||
|
|||||||
Reference in New Issue
Block a user