主题
后端正式环境数据库迁移与蓝绿部署记录
1. 文档信息
- 实施时间:2026-07-30 至 2026-07-31
- 部署目标:在同一台服务器上建立正式蓝绿环境,并将正式数据从
xiedao_dev迁移到独立的xiedao_prod - 当前结论:正式数据库迁移、蓝绿双实例部署、Nginx 切流和开机启动配置均已完成,公网正式服务正常
- 安全说明:本文不记录数据库密码、应用密钥和 PEM 证书内容
2. 当前部署架构
| 环境 | 端口 | 数据库 | 服务 | 当前职责 |
|---|---|---|---|---|
| 正式蓝 | 8080 | xiedao_prod | xiedao-prod-blue.service | 备用流量实例、执行定时任务 |
| 正式绿 | 8081 | xiedao_prod | xiedao-prod-green.service | 当前公网流量实例 |
| 开发/测试 | 8082(仅本机) | xiedao_dev | xiedao-dev.service | 开发与测试 |
当前公网调用链:
text
客户端
-> https://api.xiedao888.cn
-> Nginx
-> http://127.0.0.1:8081
-> xiedao_prod开发/测试实例仅监听 127.0.0.1:8082,通过独立域名 https://dev-api.xiedao888.cn 由 Nginx 反向代理。该 HTTPS 域名允许公网访问,但未直接开放 8082 端口。
当前 Nginx 的 API 配置统一引用正式 upstream:
nginx
proxy_pass http://xiedao_prod_api/;xiedao_prod_api 当前只包含绿色实例:
nginx
upstream xiedao_prod_api {
server 127.0.0.1:8081;
}后续蓝绿切流只修改 /etc/nginx/conf.d/xiedao_prod_api_upstream.conf 中的目标端口,不再修改正式站点的 proxy_pass。
3. 已完成工作
3.1 正式数据库
- 创建正式数据库
xiedao_prod。 - 正式数据库默认字符集为
utf8mb4,排序规则为utf8mb4_unicode_ci,与开发库一致。 - 创建正式数据库账号
xiedao_prod,正式应用不再使用开发账号连接数据库。 - 将
xiedao_dev的 176 张基础表及数据迁移到xiedao_prod。 - 迁移使用
--single-transaction在线备份方式,没有为备份停止原服务。 - 迁移后两个数据库均为 176 张基础表。
- 保留
xiedao_dev,后续供开发/测试服务使用。
3.2 正式蓝绿服务
- 建立正式蓝目录
/opt/xiedao/prod/blue。 - 建立正式绿目录
/opt/xiedao/prod/green。 - 蓝色实例使用端口
8080,绿色实例使用端口8081。 - 两个实例均明确连接
xiedao_prod。 - 创建以下 systemd 服务:
xiedao-prod-blue.servicexiedao-prod-green.service
- 两个服务均已设置为开机自动启动。
- 两个端口的
/captchaImage均已验证返回 HTTP 200。 - 旧的
/opt/xiedao/api/ruoyi-admin.jar服务已停止。 - MySQL 运行连接已确认只剩
xiedao_prod账号连接xiedao_prod。
3.3 资源与证书
- 服务器增加 4 GB Swap,并写入
/etc/fstab。 - 正式绿 JVM 参数设置为:
text
-Xms256m
-Xmx768m
-XX:MaxMetaspaceSize=256m
-XX:+UseG1GC
-XX:+ExitOnOutOfMemoryError- 正式绿日志目录为
/opt/xiedao/prod/green/logs。 - 支付证书已从 JAR 中提取到
/opt/xiedao/prod/green/cert。 - 证书文件权限设置为
600。 WECHAT_PAY_SCORE_PRIVATE_KEY_PATH已指向绿色实例的证书文件。
3.4 Nginx 切流
- Nginx 配置检查
nginx -t通过。 - 使用
systemctl reload nginx完成平滑切流,没有重启 Nginx。 - 当前公网 API 指向正式绿
8081。 - 正式站点的
proxy_pass已统一引用xiedao_prod_api,upstream 当前指向绿色8081。 8080、8081和公网/captchaImage均返回 HTTP 200。
3.5 开发/测试实例
- 建立开发/测试目录
/opt/xiedao/dev。 - 创建并启用
xiedao-dev.service,使用端口8082,仅监听127.0.0.1。 - 开发实例明确连接
xiedao_dev,使用独立账号xiedao。 - 开发实例使用
druid,devProfile,上传目录为/home/xiedao/dev-uploadPath。 - 开发实例默认关闭应用调度、Quartz、支付后台任务、微信发货同步和微信交易组件。
- 开发实例 JVM 上限为
-Xmx512m,首次启动健康检查和 Swagger 均返回 HTTP 200。 - 原
Api/deploy.bat已重命名为Api/deploy-dev.bat,仅允许发布开发环境,不再写入旧目录/opt/xiedao/api。 - 开发发布使用 systemd 重启、SHA-256 校验、版本软链接和失败自动回滚。
- 开发发布默认执行自动化测试,并记录 release ID、JAR SHA-256、Git commit、工作区状态和测试结果;显式使用
skip-tests生成的产物不得晋级正式环境。 dev-api.xiedao888.cn站点已合并到/etc/nginx/sites-available/xiedao888.cn,使用现有通配符证书;不再单独启用xiedao-dev-api配置文件。- dev HTTPS 入口允许公网访问,由 Nginx 统一提供 TLS 和反向代理。
- Nginx 配置检查通过并平滑 reload,dev 与正式公网健康接口均返回 HTTP 200。
4. 调度职责
为避免两个正式实例重复执行定时任务,当前职责如下:
| 实例 | 应用调度 | Quartz | 说明 |
|---|---|---|---|
正式蓝 8080 | 开启 | 开启 | 当前唯一调度实例 |
正式绿 8081 | 关闭 | 关闭 | 当前公网流量实例 |
正式蓝已确认包含:
text
APP_SCHEDULING_ENABLED=true
SPRING_QUARTZ_AUTO_STARTUP=true正式绿已确认包含:
text
APP_SCHEDULING_ENABLED=false
SPRING_QUARTZ_AUTO_STARTUP=false后续蓝绿发布时,Nginx 流量切换和调度职责切换是两个独立步骤。任何时刻只允许一个正式实例执行调度任务。
5. 数据迁移与核对
5.1 主要备份
首次迁移备份:
text
/root/db-backups/xiedao_dev_migration_20260730_222122.sql
大小:13 MB
建表数量:176
SHA-256:bdae18471f341eb790cc5ecdcec8f8afe5d0d25c840f903f9ee0c5389d632997切流前备份:
text
/root/db-backups/xiedao_dev_before_cutover_20260730_235428.sql
/root/db-backups/xiedao_prod_before_cutover_20260730_235428.sql切流后正式库备份:
text
/root/db-backups/xiedao_prod_after_cutover_20260731_010850.sql
大小:13 MB
建表数量:176
SHA-256:0705d854ac8a3b759cdfbecd31d05228619872d0806bdcbd06f6c16ee0317a9c5.2 数据差异处理
- 正式库保留了切流后产生的真实订单
order_id=8912及其关联数据。 - 开发库中的
sys_job_log、sys_logininfor没有直接合并到正式库,避免自增主键冲突。 - 管理员和小程序用户的最新登录信息已按时间条件同步。
- 没有使用开发库整库覆盖正式库。
- 后续禁止再用
xiedao_dev全量覆盖xiedao_prod。
6. 已知问题
6.1 拼团超时任务已暂停
Quartz 任务信息:
text
job_id=110
任务名称:拼团未成团超时处理
调用目标:xdGroupTimeoutTask.process()
当前状态:1(暂停)任务处理历史拼团 23、24 时发现对应订单 8577、8598 缺少退款规则快照。两个数据库中都缺少快照,说明这是历史数据问题,不是迁移遗漏。
在制定这两笔历史订单的退款补救方案前:
- 不要恢复任务 110。
- 不要手工伪造退款规则快照。
6.2 租车履约表缺少字段
正式蓝定时任务出现:
text
Unknown column 'd.overdue_fee_fen' in 'field list'
XdCarRentalDispatchMapper.selectDispatchList该问题可能影响:
- 租车逾期扫描和逾期标记。
- 租车履约列表与详情。
- 根据订单查询租车履约记录。
- 商户租车接单、取车、还车、取消等依赖履约查询的操作。
- 对应管理后台接口。
xd_rental_order_dispatch 也使用相同的逾期字段。如果该表字段同样缺失,还会影响租物逾期扫描、列表、详情、交付、归还和取消。
现有迁移文件 V20260729__rental_dispatch_overdue_fields.sql 只处理了 xd_rental_order_dispatch,遗漏了 xd_car_rental_dispatch。项目当前没有发现 Flyway 或 Liquibase 自动执行配置,因此服务器仍需手工执行结构修复。
在修复前应先查询两个数据库中以下字段的实际情况:
text
is_overdue
overdue_days
overdue_fee
overdue_fee_fen确认字段后,再对 xiedao_dev 和 xiedao_prod 执行幂等 DDL,并同步修复项目迁移脚本。
7. 尚未完成事项
- 检查并修复租车、租物履约表的逾期字段。
- 修复本地数据库迁移文件对
xd_car_rental_dispatch的遗漏。 - 为历史拼团订单 8577、8598 制定数据补救方案。
- 验证补救完成后再决定是否恢复任务 110。
- 修复当前自动化测试基线中的 3 个失败和 3 个错误;修复前可显式跳过测试发布 dev,但该产物无法通过正式晋级守卫。
- 使用新脚本完成首次正式发布演练,核对产物晋级、切流和 rollback 状态文件。
- 业务验收开发实例后,再执行首次新的正式发布流程。
- 后续考虑将正式 Java 服务从
root用户迁移到权限受限的专用系统账号。
8. 标准蓝绿发布流程
8.1 发布并验收 dev
默认执行全部自动化测试,测试通过后才部署:
bash
cd ~/projects/xiedao/Api
./deploy-dev.sh test仅在修复测试基线期间允许显式跳过测试:
bash
./deploy-dev.sh skip-tests每个新 dev release 都包含 release.env。正式晋级必须同时满足:
- 该 release 是
/opt/xiedao/dev/ruoyi-admin.jar当前指向的版本。 - JAR SHA-256 与清单一致。
GIT_DIRTY=false。TESTS_PASSED=true。- dev 健康检查和业务验收均已通过。
8.2 晋级到非流量正式实例
先查看当前 upstream:
bash
cat /etc/nginx/conf.d/xiedao_prod_api_upstream.conf当前为绿色 8081 时,只能晋级蓝色:
bash
./deploy-prod.sh blue <dev-release-id>当前为蓝色 8080 时,只能晋级绿色:
bash
./deploy-prod.sh green <dev-release-id>晋级脚本从服务器当前 dev release 复制同一个 JAR,不重新构建。脚本执行 SHA-256、Git/测试清单、非流量目标、调度唯一性、systemd 工作目录和端口检查;目标实例启动失败时恢复其原软链接。该步骤不修改 Nginx。
8.3 切换正式流量
目标实例验收通过后执行:
bash
./switch-prod.sh blue <promoted-release-id>或:
bash
./switch-prod.sh green <promoted-release-id>切流脚本依次执行:
- 确认目标实例正在运行指定的正式晋级 release。
- 连续三次检查目标本机健康接口。
- 备份正式 upstream。
- 只修改
xiedao_prod_api的唯一后端端口。 - 执行
nginx -t和systemctl reload nginx。 - 最多五次检查公网健康接口。
- 失败时恢复 upstream 并再次 reload。
- 成功后写入
/opt/xiedao/prod/active-traffic.env。
观察期间保留旧实例。需要回到上一次记录的槽位和 release 时执行:
bash
./switch-prod.sh rollback8.4 调度职责
- 当前蓝实例是唯一调度主实例,绿实例的应用调度与 Quartz 主开关关闭。
deploy-prod和switch-prod每次操作前后都检查恰好一个调度主实例。- 发布和切流脚本不自动修改
env.sh,也不自动交接调度职责。 - 晋级蓝实例时会重启唯一调度实例,可能产生短暂调度空窗,但不会产生双调度。
- 流量切到新版本后,旧实例继续保留观察;若随后将同一 release 晋级到旧实例以同步调度代码,将结束该旧版本的快速流量回滚窗口。
- 如需自动、无空窗地交接调度,应先将调度进程从 Web 蓝绿实例中拆分为独立服务,不在当前脚本中隐式实现。
8.5 发布原则
- 新版本先部署到非流量实例。
- 正式环境只晋级当前 dev 已验证的同一个 JAR,不重新构建。
- 先通过本机端口进行健康检查和业务验证。
- 切流前执行
nginx -t。 - 切流使用
systemctl reload nginx,不使用restart。 - 切流后同时检查本机端口、公网接口、服务日志和数据库连接。
- 发布和切流期间必须保证只有一个实例开启调度主开关。
- 旧实例保留一段观察时间,以便快速回滚。
9. 当前验收结论
截至 2026-07-31:
- Nginx:运行正常。
- 正式蓝:运行正常,负责调度。
- 正式绿:运行正常,承接公网流量。
- 正式数据库:迁移完成并已备份。
- 开发/测试实例:运行正常,仅本机监听
8082,由允许公网访问的dev-api.xiedao888.cn代理,连接xiedao_dev。 - 公网 API:HTTP 200。
- 正式服务数据库连接:已切换到
xiedao_prod。 - 整体正式服务可用,但租车/租物履约字段问题仍需优先修复。