部署、迁移、备份与回滚:让新版本可控地上线

构建成功只说明产物生成了,不等于新版本能读对数据库,也不等于发生问题后能退回。部署需要同时考虑代码、配置、数据结构和运行中的任务。

1. 一个版本不只有 Git commit

记录代码提交、依赖锁文件、运行时版本、镜像或构建产物标识,以及配置版本。环境变量中的秘密不写进仓库,但要知道生产、预览和本地分别连接哪套资源。预览环境误连生产库,比样式错误更值得提前拦住。

构建阶段检查类型、单元测试、内容与安全规则;部署后再检查真实入口、鉴权、数据库和关键业务路径。只请求一个返回静态 200 的健康接口,证明不了数据依赖可用。

2. 三类探针别混用

liveness 判断是否需要重启进程;readiness 判断当前实例是否适合接流量;startup 为慢启动过程提供单独判断窗口。若把短时数据库抖动直接作为所有实例 liveness 失败条件,可能造成同时重启,进一步放大故障。

这是 Kubernetes 配置草图,具体周期和阈值要按应用启动与恢复时间测量;/live 与 /ready 需要应用真实实现。

yaml
livenessProbe: httpGet: path: /live port: 8080 periodSeconds: 10 readinessProbe: httpGet: path: /ready port: 8080 periodSeconds: 5 startupProbe: httpGet: path: /live port: 8080 periodSeconds: 5 failureThreshold: 24

优雅退出通常先停止接收新工作,再在限定时间内收尾在途请求。后台任务还要处理租约与重投。关闭进程并不自动说明所有外部副作用都完成或撤销。

3. 滚动、蓝绿与金丝雀

滚动发布逐步替换实例;蓝绿保留两套环境再切流量;金丝雀先让少量流量使用新版本并比较指标。它们都需要兼容混合版本和共享数据。选择流量样本时考虑租户、接口和关键用户群,少量流量恰好没覆盖问题不代表全量安全。

数据库演进采用先扩展再收缩:新增兼容字段,发布能处理新旧数据的代码,回填并验证,最后移除旧结构。若新代码已经写入旧版本理解不了的数据,单纯回滚镜像可能失败。

4. 备份必须练恢复

RPO 描述可接受的数据丢失窗口,RTO 描述恢复服务所需时间目标。每天备份一次和“最多丢一小时数据”通常对不上,需要根据要求增加日志归档、复制或其他恢复方案。

复制不是备份的同义词:误删除可能很快同步到副本。备份要验证完整性、权限、加密、保留周期及恢复步骤。恢复时不仅恢复表,还要核对对象存储、消息积压、密钥与外部业务状态。

5. 发布清单

  1. 确认目标项目、环境和数据库标识,不只看项目名称。
  2. 保存构建与测试证据,准备可执行回滚步骤。
  3. 检查迁移与新旧版本兼容,先在近似数据规模上演练。
  4. 分阶段放量,观察错误、延迟、资源和业务正确性。
  5. 用正式域名验证真实读写或受控探针;保留负责人和故障操作记录。

练习从备份恢复到一个独立环境,查询关键计数并运行业务测试。若首次恢复时才发现缺少密钥或脚本,这次演练就已经暴露了有价值的问题。

参考资料

发布前运行一次旧版本兼容实验

假设把笔记标题从 title 改成 display_title。直接改名以后,旧代码仍查询 title,就可能报错。练习时先增加新字段,明确过渡期以哪个字段为准,再部署兼容读写的代码、回填并核对数据,最后才考虑移除旧字段。

在测试环境同时运行新旧版本,分别写入与读取,再尝试切回旧版。如果产生了旧版无法理解的数据,应先解决兼容策略。PostgreSQL 删除列会移除其中的数据;切换应用镜像不会把它自动恢复。

本节的核验依据

2026-10-25 查阅。下面的链接支持本节的机制说明;练习场景和选型建议是本教程的教学设计。