第20章|发布策略 1:蓝绿、金丝雀、滚动、A/B 与灰度

发布策略的本质不是“怎么把新版本放上去”,而是:怎么把风险拆开,并且随时能止损。 这一章你会得到一张“策略选择地图”:什么时候用 蓝绿,什么时候用 金丝雀, 什么时候只需要 滚动,以及 A/B灰度 到底和它们有什么关系。

Core rule

先回答“回滚要怎么做”

  • 回滚是发布策略的考试题,不是加分题
  • 回滚对象必须是上一章的 release bundle
  • 没有快速回滚,就不要激进扩流
Decision

把风险拆成三类

  • 功能风险:逻辑/兼容/数据边界
  • 性能风险:延迟、资源、缓存抖动
  • 系统风险:依赖、网络、限流、熔断
Observability

“继续扩流”必须可被指标判定

  • 至少三类指标:错误率、延迟、饱和度
  • 配套保护:阈值 + 观察窗口 + 人工接管
  • 发布标记(release marker)要能串联版本与指标

1. 先统一语言:发布策略 vs 灰度 vs A/B

这几个词经常被混用,导致“听起来都对、做起来全错”。最清晰的拆法是:

一句话总结:蓝绿/滚动/金丝雀解决“怎么换版本”,灰度/A-B 解决“谁先看到变化、看到多少、以什么指标继续”。

2. 四种常见策略,一次讲透(适用场景 / 优劣 / 回滚路径)

2.1 蓝绿(Blue-Green):一刀切切换,最像“开关电源”

蓝绿本质上是两套完全独立的生产环境:旧版本在 Blue,新版本在 Green。 切换时只改变入口路由(DNS/LB/Ingress),把流量从蓝切到绿。

2.2 滚动(Rolling):逐个替换,最像“换轮胎”

滚动发布通过逐步替换实例(Pod/VM),让新旧版本短时间共存。它是最普遍、成本最低的默认策略。

2.3 金丝雀(Canary):先给一小群“真实用户”试吃

金丝雀发布强调“按比例放量 + 指标判定”,不是简单的“先发 1 台机器”。它要配合指标与自动止损。

2.4 A/B:不是发布策略,而是实验框架

A/B 关注的是“两个方案同时在线,比较结果”。它常用于产品实验,但在工程上也能用于: 新缓存策略、新算法、新限流策略的风险验证。

策略对照矩阵:成本、风险、回滚速度与实现复杂度 建议:先按“回滚速度 + 兼容性约束 + 产能成本”三维选择 Strategy Rollback Capacity cost Compatibility risk Complexity Blue-Green very fast high (2x) medium medium Rolling medium low high (mix) low Canary fast medium medium high A/B (experiment) not a rollout varies depends very high
图 1:策略对照矩阵。选择策略前先问三件事:我能多快回滚?我能承担多少双份产能?我能否接受新旧混跑?

3. 金丝雀与灰度的“正确打开方式”:流量曲线 + 观察窗口

金丝雀最容易犯的错是:把它当成“逐步扩容”。真正的金丝雀是逐步扩流 + 指标判定。 你需要三样东西:流量切换能力发布标记自动止损

3.1 一个可复用的扩流节奏

流量切换曲线:扩流不是“越快越好”,而是“每步可判定” 横轴:时间 · 纵轴:新版本流量占比 · 关键:观察窗口 + 自动止损 100% 0% 1% 5% 10% 25% 50% 100% observe observe observe 自动止损:回滚/暂停扩大
图 2:金丝雀扩流曲线。每个台阶都需要“观察窗口 + 指标判定”,否则你只是把事故推迟到 100% 那一刻。

4. 发布判定与自动止损:让系统帮你“踩刹车”

发布失败不可怕,可怕的是你没有刹车:错误率升高、延迟飙升、资源饱和,但仍然照流程继续扩大。 一个成熟的发布系统必须把“继续/停止/回滚”做成可判定的控制面。

4.1 判定三件套

  1. 指标:error rate、latency(P95/P99)、saturation(CPU/内存/队列)
  2. 阈值:对比基线(上一版本/同区域/对照组),而不是拍脑袋绝对值
  3. 窗口:足够长以抵抗噪声,但足够短以快速止损
反直觉但常见:“发布后延迟上升”不一定是代码慢了,可能是缓存被刷新、连接池重建、热路径冷启动。判定时必须结合保护窗口与趋势。
发布控制面:门禁、观测判定与秒级止损 目标:继续扩流必须“可判定”,止损必须“可自动”,并且永远允许“人工接管” Gate 1:变更门 审批 · 策略校验 · 变更窗口 Step:扩流 1% → 10% → 50% → 100% Gate 2:数据门 指标判定 · 保护窗口 · 趋势 Judgment inputs Errors error rate, 5xx, timeouts Latency P95/P99, tail spikes Saturation CPU/mem, queues, throttling 判定结果:继续扩大 / 暂停观察 / 回滚 / 冻结发布(并保留人工接管) kill switch
图 3:发布控制面。继续扩流必须可判定(指标 + 阈值 + 窗口),止损必须可自动(回滚/冻结/暂停),并且永远允许人工接管。

5. 最小落地清单(避免“看起来在灰度,实际在赌命”)

  1. 回滚先行:回滚脚本/按钮必须比发布脚本更可靠;回滚对象是上一套 bundle。
  2. 指标基线:定义对照(上一版本/对照组/同区域),别用“单点绝对值”拍脑袋。
  3. 观察窗口:每个扩流台阶至少覆盖一个典型周期;设保护窗口避免冷启动误判。
  4. 兼容性设计:滚动/金丝雀都会短暂混跑,接口/数据/缓存 key 必须向后兼容。
  5. 秒级止损:关键路径必须有 kill switch(开关/降级/回滚),并演练。
你现在应该能做选择题:
1) 我们的系统能否承担双份产能?如果能,蓝绿会把回滚变得极快。
2) 我们是否能接受新旧混跑?如果能,滚动是默认;如果不能,优先蓝绿或金丝雀配强门禁。
3) 我们是否有足够观测与止损?如果没有,先补齐控制面,再谈金丝雀和自动判定。
← 上一章:部署基础 下一章:发布策略 2(回滚、前滚、hotfix) →