“这个版本谁批的?”“为什么紧急插了一个需求?”“回滚了怎么没人通知?”——发布是质量链路的最后一公里,也是信息最碎的一环:开发、测试、运维、产品各看各的,发布决策散落在群聊和口头里。这篇讲把发布变成"可审计的流水线":决策有记录、门禁有数据、回滚有预案、复盘有闭环。
一、发布的本质:一次风险决策,不是一次技术操作
1 2 3 4 5 6 7 8 9
| "发版"常被理解成"把包部署上去"(技术操作) 实际是:"当前质量状态 × 业务紧迫度 × 风险敞口"的决策
发布决策三要素(每次发布必须显式回答): 1. 质量状态:门禁全过?遗留缺陷清单(含"不修的理由")? 2. 业务紧迫:为什么是现在?(发版窗口/运营活动/事故修复) 3. 风险敞口:本次改动 blast radius?灰度计划?回滚预案?
三者都写在"发布单"里——没有发布单的发布 = 没有发生的发布(出了事说不清谁批的)
|
二、发布单:一份文档对齐四个角色
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| release: version: 2026.05.15 type: 常规周更 window: 2026-05-15 20:00 - 22:00(业务低峰)
quality: gates: L1 门禁: ✅ 全过(build L2 集成: ✅ 612/612(smoke+api 档) L3 回归: ✅ 1847/1850,3 失败均为已知问题 长稳: ✅ 72h 无异常(run: soak-0512) 混沌: ⏭️ 本次无架构变更,按季度计划 05-28 执行 known_issues: - id: desc: 支付超时状态偶发错乱(0.3% 概率) decision: 带病发布 reason: 有监控 + 自动对账兜底,修复在 05.22 版本 approved_by: 测试 owner(记录在案)
change: scope: 23 commits / 14 文件 / 影响模块:订单、消息 blast_radius: 订单支付链路(核心)+ 消息列表(一般) new_dependencies: 无 config_changes: - 支付超时 5s → 8s(已评估:弱网场景,压测验证通过)
rollout: canary: 1%(4h)→ 10%(24h)→ 50%(24h)→ 100% gates_ref: canary/gates/gate-{1,2,3}.yaml rollback: plan: 配置开关切回旧版本(2 分钟)+ 数据兼容确认(无 schema 变更) drill: 2026-05-10 已演练,实际耗时 3 分 12 秒 owner: 值班 SRE @张三
approval: - 测试 owner: @李四 2026-05-15 14:00(附质量状态) - 开发 owner: @王五 2026-05-15 14:10(附变更范围) - 产品: @赵六 2026-05-15 14:30(确认业务窗口) decision: GO
|
发布单的四个价值:
- 决策留痕:谁批的、基于什么数据批的、带病发布的缺陷谁拍的板——事故复盘时"谁批的"30 秒查清;
- 风险显式化:"带病发布"从潜规则变成带审批的显式决策(known_issues 每条都要理由 + 批准人);
- 四角色对齐:测试看质量、开发看范围、产品看窗口、SRE 看回滚,一份文档四个视角;
- 回滚预案可验证:演练记录(实际耗时 3 分 12 秒)让"能回滚"从承诺变成事实。
三、发布门禁:数据说话,不拍脑袋
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 门禁分两级: 1. 硬性门禁(不过不发,无例外): - P0/P1 缺陷清零(或带病发布审批链完整) - @critical 用例 100% 通过 - 回滚预案存在且 ≤ 30 天内演练过 - 发布窗口内无其他变更(变更冻结)
2. 软性门禁(可豁免,但豁免留痕 + 补偿措施): - 增量覆盖率 < 80% → 豁免需测试 owner 批 + 指定补测计划 - 长稳未完成 → 豁免需"架构变更评估:本次不涉及"声明 - 混沌未跑 → 同上
豁免机制的意义:没有例外的门禁会被"紧急发布"击穿(然后所有门禁都被击穿) 有留痕的豁免让"紧急"有成本(要拍板 + 补偿 + 周报可见)
|
四、发布日:变更冻结与"唯一事实源"
1 2 3 4 5 6 7 8 9 10 11 12 13
| 发布窗口(如周五 20:00-22:00)的规矩: 1. 变更冻结:冻结开始到全量完成,除发布本身任何变更不进生产 (配置变更/数据订正/其他 hotfix 一律排期到窗口外) 2. 唯一事实源:发布状态只看发布平台(不看群聊) - 平台状态机:准备中 → 金丝雀中 → 10% → 50% → 全量 → 完成/已回滚 - 每个状态变更自动通知(钉钉/飞书):谁、什么时间、什么状态、附指标快照 - 群里的"我这边好了"不算数,平台状态才算数 3. 值班分工:发布日固定三角(测试/开发/SRE 各 1 人), 平台上一键看到"现在谁在岗" 4. 事故升级路径预演: 金丝雀指标越界 → 自动回滚(不用人决策) 业务指标异常 → 暂停放大,三角会商 10 分钟内决策(继续/回滚/观察) 决策超时未响应 → 默认回滚(安全侧默认值)
|
"决策超时默认回滚"是发布制度的安全哲学:发布日最贵的不是回滚,是"僵在中间状态"——半灰度挂着,所有人盯着大盘,谁都不敢拍板。
五、发布后 72 小时:观察期与复盘
1 2 3 4 5 6 7 8 9 10 11 12 13
| 发布后观察期(72h,自动): 1. 指标基线对比:新版本 vs 上一版本(同口径 72h 曲线) 2. 缺陷监听:新版本缺陷自动关联版本标签 3. 灰度拦截复盘:发布后 72h 发现的缺陷 vs 发布单 known_issues ——known_issues 没列出的"带病"缺陷 = 发布决策漏了风险
发布复盘(每次发布必做,1 小时封顶): 1. 门禁数据 vs 实际(门禁说全过,线上还是出了事?为什么?) 2. 时间线还原(平台状态机自动导出) 3. 改进项(≤ 3 个,带 owner 和期限,进跟踪表) 4. 月度汇总:发布成功率/回滚率/回滚耗时/带病发布缺陷复发率 ——"带病发布缺陷复发率"是发布决策质量的终极指标: 拍板"带病发"的缺陷后来复发了几次?复发多了说明风险评估失准
|
六、和测试体系的其他部分
1 2 3 4 5
| 发布管理在体系中的位置: - 门禁数据源:CI 流水线(L1/L2/L3)+ 长稳 + 混沌 + 灰度判据 - 缺陷管理:known_issues 的每条 = 缺陷单的引用 + 决策记录 - 度量:发布成功率/回滚率进质量看板,和缺陷趋势同屏 - 发布单 = 所有测试数据的"汇总结论页"(测试产出的最后一站)
|
七、小结
发布管理工程化四个支柱:发布单(四角色一份文档,决策留痕)、两级门禁(硬性无例外,软性豁免留痕)、变更冻结 + 唯一事实源(状态只看平台)、72h 观察 + 复盘(known_issues 对照,带病发布复发率)。核心转变:发布从"群里的集体吼一嗓子"变成"平台上的状态机"——每一次决策都有数据、有审批、有时间线、有复盘,出事了 30 秒还原现场,没出事也积累下一版的判断依据。