Skip to content

后端正式环境数据库迁移与蓝绿部署记录 ​

1. 文档信息 ​

  • 实施时间:2026-07-30 至 2026-07-31
  • 部署目标:在同一台服务器上建立正式蓝绿环境,并将正式数据从 xiedao_dev 迁移到独立的 xiedao_prod
  • 当前结论:正式数据库迁移、蓝绿双实例部署、Nginx 切流和开机启动配置均已完成,公网正式服务正常
  • 安全说明:本文不记录数据库密码、应用密钥和 PEM 证书内容

2. 当前部署架构 ​

环境端口数据库服务当前职责
正式蓝8080xiedao_prodxiedao-prod-blue.service备用流量实例、执行定时任务
正式绿8081xiedao_prodxiedao-prod-green.service当前公网流量实例
开发/测试8082(仅本机)xiedao_devxiedao-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.service
    • xiedao-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,dev Profile,上传目录为 /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:0705d854ac8a3b759cdfbecd31d05228619872d0806bdcbd06f6c16ee0317a9c

5.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. 尚未完成事项 ​

  1. 检查并修复租车、租物履约表的逾期字段。
  2. 修复本地数据库迁移文件对 xd_car_rental_dispatch 的遗漏。
  3. 为历史拼团订单 8577、8598 制定数据补救方案。
  4. 验证补救完成后再决定是否恢复任务 110。
  5. 修复当前自动化测试基线中的 3 个失败和 3 个错误;修复前可显式跳过测试发布 dev,但该产物无法通过正式晋级守卫。
  6. 使用新脚本完成首次正式发布演练,核对产物晋级、切流和 rollback 状态文件。
  7. 业务验收开发实例后,再执行首次新的正式发布流程。
  8. 后续考虑将正式 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>

切流脚本依次执行:

  1. 确认目标实例正在运行指定的正式晋级 release。
  2. 连续三次检查目标本机健康接口。
  3. 备份正式 upstream。
  4. 只修改 xiedao_prod_api 的唯一后端端口。
  5. 执行 nginx -t 和 systemctl reload nginx。
  6. 最多五次检查公网健康接口。
  7. 失败时恢复 upstream 并再次 reload。
  8. 成功后写入 /opt/xiedao/prod/active-traffic.env。

观察期间保留旧实例。需要回到上一次记录的槽位和 release 时执行:

bash
./switch-prod.sh rollback

8.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。
  • 整体正式服务可用,但租车/租物履约字段问题仍需优先修复。

携岛 XieDao · 内部文档