部署与发布 — 让上线变成一次可撤销的操作

一句话:部署是把同一个制品搬进环境,发布是决定让多少用户看到它;把这两件事分开,上线就从「事件」变成了「动作」。

🎯 这 20% 能解决哪些问题

你遇到的困惑本质原因马上能改的动作
测试环境好好的,线上就崩环境与配置靠手工维护,不一致同一制品晋级,配置从环境变量/配置中心注入
上线时间总在深夜,还要全员盯着没有灰度能力,只能一把梭先做金丝雀 5% 流量观察 30 分钟
数据库改字段导致代码报错代码与表结构同时上线,互相不兼容用「先加 → 双写 → 读新 → 删旧」四步迁移
出问题回滚要重装环境制品不可回溯,部署脚本幂等性差每次构建留不可变版本号,回滚 = 切回上一个版本
一个功能想先给内部用只能用分支或注释代码控制用 Feature Flag 控制开关,不靠改代码

一、三个概念先分清

概念是什么关键要求
构建 Build把源码变成制品(镜像/包)一次构建,处处运行;带版本号与提交哈希
部署 Deploy把制品放进某个环境并启动幂等、可重复、不依赖人工步骤
发布 Release把流量切给新版本可分批、可暂停、可回退
flowchart LR
    C["提交代码"] --> B["构建制品<br/>版本号 + 哈希"]
    B --> T["测试环境<br/>自动部署"]
    T --> S["预发环境<br/>同构校验"]
    S --> G["灰度 5%<br/>观察指标"]
    G -->|"指标达标"| F["全量发布"]
    G -->|"指标异常"| R["回滚到上一版本"]

核心规律:制品一旦构建就不再修改;环境之间只搬同一个制品,不允许「在服务器上改一行」。


二、配置与密钥:代码里一个都不能有

内容放哪禁止
环境差异(域名、端口、第三方地址)环境变量 / 配置中心写进代码分支判断
密钥、证书、Token密钥管理服务 / CI 变量提交到仓库,或放在镜像里
业务开关与阈值Feature Flag / 配置中心改代码重新发版
日志级别、采样率环境变量,支持热更新硬编码

判据:把仓库公开也不该泄露任何可用凭据;切换环境只需要换一份变量文件。


三、数据库变更:唯一不能回滚的地方

3.1 expand-contract 四步法

flowchart LR
    E["Expand<br/>加新字段/新表"] --> D["Dual Write<br/>新旧同时写"]
    D --> M["Migrate<br/>回填历史数据"]
    M --> R["Read New<br/>读切到新字段"]
    R --> C["Contract<br/>删旧字段"]
步骤动作可回滚性
Expand只加字段/表,不改不删完全可回滚
Dual Write代码双写,新字段可为空可回滚
Migrate后台任务分批回填,可重入可回滚
Read New读切新字段,观察一轮可回滚(切回读旧)
Contract删除旧字段不可回滚,必须最后做

三条铁律:

  1. 任何一次发布,代码必须兼容上一个版本的表结构(滚动更新期间新旧代码并存)。
  2. 大表加索引、改类型必须评估锁表时间,走在线变更工具或低峰执行。
  3. 删除操作永远单独一次发布,且提前备份。

四、发布策略:按风险选,不按潮流选

策略怎么切流量回滚速度资源成本适用
重建(停机)停旧起新慢低内部工具、可停机系统
滚动更新逐批替换实例中(再滚一次)低无状态服务默认选择
蓝绿整组切换秒级(切回旧组)高(双份资源)核心服务、需秒级回退
金丝雀按比例放量 1%→5%→50%→100%秒级(摘流量)低用户量大、影响面敏感

4.1 灰度判定:看这四个指标

指标达标线(相对基线)不达标动作
错误率不高于基线 +0.1%,且绝对值 <0.5%立即回滚
P99 延迟不高于基线 20%暂停放量,排查
资源饱和度CPU/内存 <80%暂停放量
业务指标下单/支付成功率不下降立即回滚

核心规律:灰度不是等时间,是等指标。指标不达标,5 分钟就退。


五、回滚预案:发布前必须写好的三行

1. 回滚动作:把流量切回上一版本 <版本号>(命令/按钮在哪)
2. 数据影响:本次是否含不可逆变更(迁移/删字段)→ 有则先做备份
3. 判定人:谁在什么指标下有权按下回滚(不需要开会)
项要求
触发条件提前写死阈值,不靠现场感觉
执行人值班人能独立执行,不需要作者在线
演练预发环境至少演练一次,记录耗时
目标时长3 分钟内完成回滚

六、Feature Flag:把「发布」和「上线」再拆一层

用途好处注意
未完成功能隐藏代码可以持续合并,不用长命分支开关必须有到期日
灰度放量按用户/租户/地区开启开关组合要有默认值
快速止血关开关比回滚更快关键路径不能依赖远程配置可用性
实验对比A/B 测试同一份代码避免开关嵌套地狱

规范:每个开关有负责人、默认值、清理时间;超过 3 个月未清理的开关视为技术债。


七、版本与发布节奏

项规则
版本号语义化 主.次.补丁:破坏性变更升主,新增功能升次,修复升补丁
发布窗口避开业务高峰与人员稀少时段;核心系统避免周五晚发布
发布记录每次记录:版本、变更项、影响范围、回滚版本、操作人
变更审批高风险变更(数据/权限/支付)需第二人复核
发布后观察至少 30 分钟盯四个指标,再离场

🎓 实战场景(TIL)

  • 场景:发布回滚后错误依旧。本质:代码可回滚,但数据库迁移与配置不可回滚。要点:迁移只加不删(扩展-收缩两步),旧代码必须能跟新表共存,回滚先退流量再退制品。
  • 场景:上线那一分钟集中大量 5xx。本质:全量切换,新实例未预热(连接池、缓存、JIT)就接流。要点:金丝雀 + 小比例引流先验证错误率与 P99,健康检查通过后再逐步放开。
  • 场景:同一制品在测试环境正常、生产报错。本质:环境不一致(配置、依赖版本、镜像基底)。要点:制品一次构建处处运行,差异全进环境变量;发布前跑一次环境 diff 检查。

📋 一页速查

我要做照着做
判断能否发布制品有版本号、测试门禁通过、回滚三步写好、数据变更有备份
选发布策略无状态默认滚动;核心服务蓝绿;用户量大用金丝雀
做数据库变更expand → dual write → migrate → read new → contract,删字段单独发
判断灰度是否继续错误率、P99、饱和度、业务成功率四项全达标才放量
回滚切流量到上一版本,目标 3 分钟内;不可逆数据变更先备份
管开关每个 Flag 有负责人 + 默认值 + 清理日期
发布后观察 30 分钟四个指标,记录发布日志

🔗 相关链接