小区门口有一家“老四川火锅”,靠一锅麻辣鲜香的红油底料火了整整十年。老板老张研发了一本新菜单,想升级店面,却始终不敢轻举妄动——万一顾客吃不惯新口味,或者厨房新设备掉链子,十年口碑就砸了。他琢磨出两条路:第一条,在马路对面悄悄盘下一家新店面,把新菜单、新厨房、新服务员全部准备好,确认没问题后,在一个周末把全体顾客一次性请进新店;万一宾客抱怨,立刻关门、换回招牌,让顾客坐回老店的老座位——软件工程里这叫“蓝绿部署”(Blue-Green)。第二条,老店照常营业,只在门口摆个小试吃窗口,让 10% 戴着红帽子的“体验官”先试新菜,确认没有差评,再把试吃比例逐步提到 50%、100%——这叫“金丝雀部署”(Canary)。这两条路合起来,就是现代大厂保障服务稳定性的核心打法:渐进式交付。本文就用老张开火锅店的思路,把这套打法掰开揉碎讲清楚。

岗位关联

掌握渐进式交付,你就掌握了把发布事故从“全网瘫痪”压缩成“小范围波动”的能力——这是 SRE 可靠性工程最值钱的核心技能,也是大厂架构师面试的必考题。

目录
  1. 可视化演示
  2. 双雄对比——隔壁新店还是试吃窗口?
  3. 流量切换——门口的号牌怎么发
  4. 自动化测试——神秘顾客先试菜
  5. 监控告警——生意仪表盘
  6. 回滚设计——招牌一翻的撤店预案
  7. 场景选型——新菜单还是新店面?
  8. 容量规划——新店扛得住晚高峰吗?
  9. 架构落地——开店手册与发布流水线
  10. AI 应用场景
  11. Python 演示
  12. 常见误区
  13. 面试题

可视化演示

动态展示权重金丝雀发布、Blue-Green蓝绿切换、指标门控回滚与影子部署四种渐进式交付策略的核心机制。

本节配有交互动效(进入视口后自动加载,约 3KB)。

双雄对比——隔壁新店还是试吃窗口?

面对新菜单,老张有两个方案。方案一走“隔壁新店”路线:先盘下马路对面的店面,把装修、设备、厨师全部配齐,等一切就绪后,在一个周末把客流整体迁入新店。方案二走“试吃窗口”路线:老店照常营业,只在门口支起一个窗口,让一小撮戴红帽子的顾客先试新菜,验证没有差评再逐步推广。

技术世界里,方案一就是 Blue-Green 部署:同时维护两套生产环境,一套跑当前版本(Blue),一套跑新版本(Green)。正式发布时,通过负载均衡把线上流量一次性切到 Green;一旦发现异常,再把流量切回 Blue,整个过程以秒计。方案二就是 Canary 部署:先部署新版本实例,只接收 10% 的真实流量,观察无误后逐步放量到 100%。

两者的本质差异集中在三点:切换粒度上一个是一次性、一个是渐进式;资源成本上一个要维持双份环境、一个是增量扩容;回滚速度上一个秒级完成、一个依赖当前放量进度。如果一句话概括:Blue-Green 押注“切换得快”,Canary 押注“试得小心”。

就像老张租下新店面后老店也不能关——房租、水电、后厨人手都得付双份。试吃窗口(Canary)只有添几口锅的成本,而 Blue-Green 从一开始就做好了“双倍房租”的预算。理解了这个成本结构,你才能在实际选型时不只看到回滚快,也看到账单贵。

Cbg=2×Cs\displaystyle C_{\text{bg}} = 2 \times C_s
Blue-Green 部署的资源总成本是单套生产环境的两倍,这就是它最直白的代价。
  1. 单套环境成本一套生产环境的日常开销,包含服务器、带宽、存储和运维人力
    CsC_s
  2. 双倍系数Blue-Green 必须同时维持新旧两套环境在线,成本直接翻倍
    22
  3. 蓝绿总成本两个环境同时运行,总资源成本等于单套成本乘上双倍系数
    CbgC_{\text{bg}}

流量切换——门口的号牌怎么发

试吃窗口开起来了,可怎么让顾客愿意去窗口?老张在门口发号牌:每 10 个号里,有 1 个盖着红章,凭红章才能去试吃窗口领新菜。红章的比例就是“流量权重”。

软件世界里的号牌是负载均衡器的权重配置。把新版本实例组的权重设为 10%,路由层就会把大约十分之一的请求转发过去。Canary 的放量序列通常设计成 10% → 25% → 50% → 100%,每一档停留一段时间观察指标;如果一切平稳,就继续放大。Blue-Green 则只有两档——0% 和 100%,一条切换指令完成全量迁移,没有中间态。

为什么用等比序列而不是每次加 10%?因为风险增长要与观察数据匹配:一开始多试一点,后面逐步保守。等比放量下,第 n 轮的比例 P_n 等于初始比例 P_0 乘以放大倍数 r 的 n 次方。

红章号牌从每 10 张发 1 张,逐步加到 2 张、4 张、8 张。顾客一点点被引导到新店,老店的座位始终保持多数,随时能把客人请回来。这就是渐进式交付的精髓——不是一刀切,而是有节奏地放水。

Pn=P0×rn\displaystyle P_n = P_0 \times r^n
Canary 的放量序列通常按等比数列递增,比如 10% → 20% → 40% → 80%,用指数放大快速逼近全量。
  1. 初始放量比例第一轮分给新版本的流量占比,经验值取 0.1,即 10%
    P0=0.1P_0 = 0.1
  2. 放大倍数每一轮放大的倍数,r = 2 表示从 10% 涨到 20%、40%、80%
    r=2r = 2
  3. 轮次编号从 0 开始计数的第几轮放量,每轮之间留出观察窗口
    n=0,1,2,…n = 0, 1, 2, \ldots
  4. 第 n 轮比例初始比例乘以放大倍数的 n 次方,得到当前轮的目标权重
    Pn=0.1×2n=10%,20%,40%,80%P_n = 0.1 \times 2^n = 10\%, 20\%, 40\%, 80\%

自动化测试——神秘顾客先试菜

新店开张前,老张请了一批“神秘顾客”:他们不亮身份,把菜单上 300 道菜全部点一遍,挑剔地催单、退菜、提要求,最后写一份详尽的试菜报告。这批神秘顾客就是软件世界的自动化测试。

测试分两层。冒烟测试(Smoke Test)只试最核心的流程:能点菜、能下单、能付款,主链路通了才谈其他;全量回归则把 300 道菜吃个遍,确保任何一个边缘功能都没被改坏。两层都过了,才轮到“发布门禁”拍板——测试通过率必须达到门槛,流水线才允许进入放量环节。

发布门禁在 CI/CD 里是一道硬闸门:自动化测试套件运行完毕后,统计通过用例数与失败用例数,算出通过率。冒烟测试要求百发百中,全量回归允许极少量已知缺陷(一般要求 99% 以上),任何一项不达标,部署直接终止,版本根本到不了流量切换那一步。

神秘顾客全部给出“满意”,老张才敢把红章号牌发出去;如果有一道菜出了问题,先改菜谱再谈试吃。自动化测试的意义正是把“新版本能不能上路”这个判断题,从拍脑袋变成看数据。

Tpass=NpassedNpassed+Nfailed≥Tthreshold\displaystyle T_{\text{pass}} = \frac{N_{\text{passed}}}{N_{\text{passed}} + N_{\text{failed}}} \geq T_{\text{threshold}}
测试通过率 = 通过用例数 ÷ 总用例数,必须大于等于发布门禁阈值(通常取 0.99)才允许放量。
  1. 通过用例数自动化测试中验证成功的用例条数,如 990 条
    NpassedN_{\text{passed}}
  2. 失败用例数验证失败的用例条数,冒烟测试中不允许任何失败
    NfailedN_{\text{failed}}
  3. 测试通过率通过用例占全部用例的比例,分子分母单位相同所以量纲为 1
    Tpass=NpassedNpassed+NfailedT_{\text{pass}} = \frac{N_{\text{passed}}}{N_{\text{passed}} + N_{\text{failed}}}
  4. 门禁阈值发布放行的最低标准,多数团队定为 0.99 甚至 1.0
    Tthreshold=0.99T_{\text{threshold}} = 0.99

监控告警——生意仪表盘

试吃期间,老张在收银台架了一块“生意仪表盘”:差评率、翻台率、等位时长。哪天翻台率突然下跌,说明客人吃得慢或者不满意,他就得立刻警觉。技术世界的仪表盘叫监控系统,SRE 靠它判断发布是否安全。

发布期最该盯三类指标:错误率(HTTP 5xx、异常堆栈)、性能指标(P99 响应延迟)、业务指标(订单成功率、支付转化率)。但这些裸数字本身说明不了问题——错误率 2% 算高吗?要看平时是多少。于是有了异常检测算法:把当前观测值和历史基线做对比,用标准差衡量“偏了多少”。

Z-score 是最常用的方法:用当前值减去基线均值,再除以标准差。Z 值在 ±3 以内属于正常波动,超过 3 就说明指标出现了统计意义上的显著异常。发布监控里,一旦 Z 值越过阈值,系统立即告警并自动暂停放量。

差评率从 1% 涨到 5%,而往日波动只有 0.5%,老张立刻知道“出事了”,不用等顾客骂上门。监控告警就是把“感知风险”从人的直觉升级成数学判断,让系统自己喊救命。

Z=x−μσ\displaystyle Z = \frac{x - \mu}{\sigma}
Z-score 衡量当前观测值偏离历史基线的程度,Z 越大说明越异常,通常 Z > 3 触发告警。
  1. 当前观测值此刻监控到的实时指标,比如当前错误率 5%
    x=0.05x = 0.05
  2. 基线均值过去 14 天同时段的平均错误率,比如 1%
    μ=0.01\mu = 0.01
  3. 标准差历史数据的波动幅度,比如 0.5%,波动小说明系统一向稳定
    σ=0.005\sigma = 0.005
  4. 偏离分数代入公式计算,Z = 8 表示严重偏离正常范围,必须告警
    Z=0.05−0.010.005=8Z = \frac{0.05 - 0.01}{0.005} = 8

回滚设计——招牌一翻的撤店预案

老张的撤店预案说穿了一文不值:招牌翻面、引导牌一换,顾客回老店,炉火不熄。价值全在“炉火不熄”四个字上——Blue 环境一直热着,回滚才有意义。

发布系统的回滚同样追求秒级。Blue-Green 的回滚就是一条流量切换指令,把入口从 Green 指回 Blue;Canary 的回滚是把放量权重调回 0,所有请求回到旧版本。两者都不需要重新构建代码或重启集群,这就是“流量级回滚”和“重新部署回滚”的本质区别。

但回滚有两个前置条件不能忽略。第一是数据兼容:新旧版本共享同一个数据库时,新版本的 schema 变更必须向后兼容(只增列、不改列、不删列),否则流量切回 Blue 后,旧代码读不懂新数据,故障依旧。第二是回滚验证:切完流量要立刻检查旧版本的错误率是否真的回落,避免反复横跳。触发逻辑用监控的 Z-score 判定:当错误率偏离超过阈值,自动执行回滚。

炉火不熄,招牌一翻,顾客就能坐回老座位。Blue-Green 秒级回滚的底气在于旧环境始终在线;Canary 回滚的底气在于权重归零的瞬间路由就绕开新版本。回滚设计不是演练,而是刻进发布流水线里的默认动作。

Rollback  ⟺  Zerr>Zthreshold\displaystyle \text{Rollback} \iff Z_{\text{err}} > Z_{\text{threshold}}
回滚决策可以表达为一个逻辑等价式:当错误率的 Z-score 超过预设阈值时,系统自动执行回滚。
  1. 错误率偏离分数当前错误率指标的 Z-score,由上一节公式实时计算
    ZerrZ_{\text{err}}
  2. 回滚阈值触发回滚的临界值,SRE 团队通常设为 3,相当于 3 倍标准差
    Zthreshold=3Z_{\text{threshold}} = 3
  3. 等价判定条件成立即自动回滚,否则继续观察或继续放量
    Rollback  ⟺  (Zerr>3)\text{Rollback} \iff (Z_{\text{err}} > 3)

场景选型——新菜单还是新店面?

如果只是菜单上换 5 道菜,老张根本不用租新店面,开个试吃窗口就够;但如果整个店面重新装修、厨房设备全换、招牌都要重做,那就得把新店准备妥当再整体切换。选型的第一原则:跟着风险走。

风险可以用“爆炸半径”量化——新版本有缺陷的概率乘以受影响用户数。半径大的变更(核心链路重构、数据库大版本升级)优先 Blue-Green,因为回滚快、兜底强;半径小的迭代(UI 调整、文案修改、小功能上线)用 Canary,既省资源又能用真实流量验证。资源预算也是硬约束:Blue-Green 的双倍成本不是所有团队都扛得住,预算紧就只能 Canary。

数据库变更是选型里最敏感的信号。新旧版本共用一个库时,schema 不兼容的发布几乎必须走 Blue-Green——Canary 阶段新老代码同时读写、互相踩踏的风险极高。反之,只要 schema 变更能保持向前兼容,Canary 的渐进放量反而更能暴露数据层问题。

换 5 道菜,试吃窗口足够;整体装修,就得备好新店再切换。场景选型的本质是在“出事的概率”和“出事的代价”之间找平衡点——概率高代价小用 Canary,概率低代价大用 Blue-Green,两者都大就必须先把风险降下来。

Rimpact=Pdefect×Nusers\displaystyle R_{\text{impact}} = P_{\text{defect}} \times N_{\text{users}}
爆炸半径 = 缺陷概率 × 影响用户数,它量化了一次发布失误的破坏范围,是选型的关键参考。
  1. 缺陷概率新版本在某功能点出 bug 的概率,由测试覆盖率、代码评审和历史经验综合估算
    PdefectP_{\text{defect}}
  2. 影响用户数若缺陷真实发生,受波及的最大用户规模,核心链路可能等于全部用户
    NusersN_{\text{users}}
  3. 爆炸半径两者相乘得到预期破坏范围,半径越大越需要 Blue-Green 的快速回滚兜底
    Rimpact=Pdefect×NusersR_{\text{impact}} = P_{\text{defect}} \times N_{\text{users}}

容量规划——新店扛得住晚高峰吗?

新店装修好了,老张最担心的是周末晚高峰的爆单。他请了一位数据专家,用过去一年的客流数据训练预测模型,生成“史上最挤周末”的客流曲线,然后按这个曲线做一次满负荷试营业。真正的容量规划,永远是发布前而不是发布后做的事。

技术上,发布前必须对新版本集群做负载测试:用压测工具按预估峰值的 1.5 到 2 倍加压,观察 CPU、内存、QPS、响应时间是否击穿。容量规划的核心是算准峰值——不能按平均流量配资源,要给突发留余量。峰值容量等于平均负载乘以突发系数加一。

对 AI 云服务来说,这一步尤其关键。大模型推理服务的资源消耗随请求上下文长度剧烈波动,容量规划要用历史流量训练预测模型,模拟大促、热点事件、恶意爬虫等极端场景。压测发现 Green 环境容量不足,就要在切换前先扩容,否则“一切换就雪崩”。

老张用 AI 模拟了“史上最挤的周末”,发现新厨房同时只能出 80 桌菜,于是提前扩容到 120 桌。容量不够之前,切换计划绝不启动——渐进式交付不只是管“怎么上线”,还管“上线后扛不扛得住”。

Cpeak=Qavg×(1+k)\displaystyle C_{\text{peak}} = Q_{\text{avg}} \times (1 + k)
峰值容量 = 平均负载 ×(1 + 突发系数),它告诉你系统至少要准备多少资源才能扛住最忙的时刻。
  1. 平均负载日均请求量或平均并发数,比如网关平均每秒 5000 个请求
    Qavg=5000Q_{\text{avg}} = 5000
  2. 突发系数峰值比平时高出的比例,电商晚高峰可取 0.8,大促可能取 2 以上
    k=0.8k = 0.8
  3. 峰值容量代入公式得到系统容量下限,本例需要支撑每秒 9000 个请求
    Cpeak=5000×(1+0.8)=9000C_{\text{peak}} = 5000 \times (1 + 0.8) = 9000

架构落地——开店手册与发布流水线

半年后,老张把“试吃窗口 + 新店预案 + 生意仪表盘”写进了《老四川开店手册》,每家分店都按手册执行。企业的做法是把这套打法沉淀成发布流水线(CI/CD Pipeline),让渐进式交付从“个人经验”变成“组织能力”。

落地形态是自动化的:代码合并触发构建,构建完成自动跑测试门禁,通过后部署到 Green 环境,冒烟验证完毕,工程师只需点一个“发布”按钮,系统就按预设策略执行 Canary 放量或 Blue-Green 切换。策略配置化、操作可审计、每一步都有监控闸门,这就是企业级发布平台的标准形态。

架构落地的另一面是成本与性能的平衡:Blue-Green 的 Green 环境空闲时可以缩容到最小副本,切换前再扩容;Canary 的放量节奏可以根据监控自动加速或暂停。最终衡量这套体系的价值,用可用性公式最直观——渐进式交付让系统“少出故障”(拉长 MTBF),同时让故障“恢复更快”(缩短 MTTR),两个因子同时优化。

老张的分店越来越多,但每家店的菜单升级都按手册走:神秘顾客试菜、仪表盘盯数据、老店炉火不熄、逐级放量切换。十年招牌靠的不是某一次超常发挥,而是一套可复制、可审计的风险控制流程——这正是企业级渐进式交付的终极形态。

A=MTBFMTBF+MTTR\displaystyle A = \frac{\text{MTBF}}{\text{MTBF} + \text{MTTR}}
系统可用性 = 平均无故障时间 ÷(平均无故障时间 + 平均恢复时间),渐进式交付同时拉长分子、缩短分母。
  1. 平均无故障时间系统持续正常运行的平均时长,发布风险受控后故障发生频次下降,MTBF 变长
    MTBF\text{MTBF}
  2. 平均恢复时间出故障后恢复服务的平均耗时,流量级回滚把 MTTR 从“小时级重装”压到“秒级切换”
    MTTR\text{MTTR}
  3. 可用性计算MTBF 越长、MTTR 越短,可用性越接近 100%,两者共同决定服务的可靠性上限
    A=MTBFMTBF+MTTRA = \frac{\text{MTBF}}{\text{MTBF} + \text{MTTR}}

AI 应用场景

金融支付:新交易链路的 Canary 放量

阶段:模型上线发布验证

解决的问题:支付系统升级新交易链路时,任何余额计算、风控判断的错误都可能造成资金损失。传统做法是停机升级,风险高且影响用户体验;AI 风控模型接入前用 Canary 放量,能以最小流量暴露真实环境中的问题。

具体案例:某支付平台在新交易链路版本发布时,先放量 1% 给内部白名单员工,同时用 AI 风控模型实时对比新旧链路的交易异常率。确认无差异后,再按 10% → 25% → 50% 逐级放量,每一档停留 30 分钟观察指标。第 4 档放量到 50% 时监控发现 P99 延迟升高了 3 倍,系统自动回滚,故障影响被控制在 50% 流量以内。

电商大促:Blue-Green 双集群压测切换

阶段:AI 负载测试与容量规划

解决的问题:双 11 大促前,核心下单服务不敢直接升级——一旦新版本扛不住峰值流量,整场大促就毁了。用 Blue-Green 搭建一套与线上完全一致的影子集群,先用 AI 流量预测模型生成大促峰值曲线,再对 Green 集群做 2 倍峰值压测,验证通过后才允许切换。

具体案例:某电商平台在大促前 3 周部署 Blue-Green 双集群,Green 集群复刻全部订单逻辑。AI 预测模型输出大促当天峰值 QPS 为平时的 6 倍,压测平台按 12 倍 QPS 对 Green 加压 1 小时,发现数据库连接池成为瓶颈。团队扩容连接池并调优参数后复测通过,大促当天一键切换流量,全程零事故。

AI 大模型网关:新模型灰度上线

阶段:模型版本迭代与效果验证

解决的问题:LLM 服务的新版本模型效果未充分验证,直接全量替换可能让回答质量劣化,引发用户流失。通过 Canary 灰度,先让 5% 的推理请求路由到新模型,用 AI 评估器对比新旧模型的响应质量、延迟和拒绝率。

具体案例:某大模型 API 平台上线新微调版本时,网关将 5% 请求路由到新模型,监控显示新模型在代码生成任务上胜率提升 12%,但推理延迟增加了 40%。团队在延迟优化后继续放量到 30%,再观察 48 小时,确认无退化后完成全量切换并回收旧模型实例。

Python 演示

python69 行
import random random.seed(42)  class Deployment:    def __init__(self, version, weight):        self.version = version        self.weight = weight  class ReleaseManager:    def __init__(self):        self.blue = Deployment("v1.0", 1.0)        self.green = None        self.rollback_count = 0     def deploy_green(self, version):        self.green = Deployment(version, 0.0)     def set_canary_ratio(self, ratio):        if self.green is None:            return        self.green.weight = ratio        self.blue.weight = 1.0 - ratio     def route(self):        if self.green is None or self.green.weight <= 0:            return self.blue        candidates = [self.blue, self.green]        weights = [self.blue.weight, self.green.weight]        return random.choices(candidates, weights=weights, k=1)[0]     def health_check(self, error_rate, max_error=0.03):        if self.green and error_rate > max_error:            self.rollback()            return True        return False     def rollback(self):        self.blue.weight = 1.0        if self.green:            self.green.weight = 0.0        self.rollback_count += 1  def simulate():    rm = ReleaseManager()    rm.deploy_green("v2.0")    for ratio in [0.1, 0.25, 0.5, 1.0]:        rm.set_canary_ratio(ratio)        errors = 0        total = 1000        for _ in range(total):            target = rm.route()            defect_rate = 0.06 if target.version == "v2.0" else 0.01            if random.random() < defect_rate:                errors += 1        error_rate = errors / total        print(f"canary {int(ratio * 100)}%: error_rate={error_rate:.2%}")        if rm.health_check(error_rate, max_error=0.03):            print("!!! rollback to blue immediately")            break    else:        print("all traffic on green: success")  if __name__ == "__main__":    simulate()
目的:模拟 Canary 渐进放量过程,演示新版本缺陷率 6% 时,放量到 50% 触发监控阈值并自动回滚的完整流程。
  1. rm = ReleaseManager()创建发布管理器,初始化 Blue 环境承载全部流量,Green 环境尚未部署
  2. rm.deploy_green("v2.0")把新版本部署到 Green 环境,初始权重为 0,不影响线上流量
  3. rm.set_canary_ratio(ratio)把新版本流量权重调整为 ratio,旧版本自动变为 1 - ratio
  4. random.choices(candidates, weights=weights, k=1)[0]按权重随机选择一个环境来处理请求,实现加权路由
  5. defect_rate = 0.06 if target.version == "v2.0" else 0.01模拟新版本缺陷率 6% 而旧版本仅 1%,制造发布风险
  6. if rm.health_check(error_rate, max_error=0.03):实时检查错误率是否超过 3% 阈值,超标立即触发 rollback()

常见误区

误区很多人觉得 Blue-Green 和 A/B 测试都是“准备两套环境让用户分流”,本质上是一回事,可以互相替代。

正解两者的目的完全不同。Blue-Green 是为了“降低发布风险”,两套环境跑不同版本,但流量只会被切到其中一套,目的是快速回滚;A/B 测试是为了“验证业务假设”,两套方案同时接收流量做对比实验,目的是找最优方案。火锅店把顾客一次性请进新店是为了换菜单,而让 100 桌客人分别吃新旧菜单并记录满意度,那才是 A/B 测试。

为何常见:两者都涉及“两套环境 + 流量拆分”,表象相似,但一个着眼稳定性、一个着眼业务增长,目标不同导致整套设计逻辑不同。

误区看到流量全部切到新版本,很多人就宣布“发布成功”,关掉监控、回收旧环境,松一口气去庆祝了。

正解放量到 100% 只是“切换完成”,不是“交付完成”。新版本还需要一段观察期(通常 24 到 72 小时)持续监控错误率和业务指标,确认稳定后才能回收旧环境。如果 100% 流量切过去但只观察了几分钟,那些只在高峰时段出现的隐患(内存泄漏、慢查询)根本来不及暴露。

为何常见:把“流量切换”误解为“发布成功”,忽略了渐进式交付的闭环——发布要经过“放量 → 观察 → 稳定 → 回收”四个阶段才算真正结束。

误区以为有了两套完全隔离的环境,数据库想怎么改都行,反正出问题一键切回 Blue 就万事大吉。

正解如果新旧版本共享同一个数据库,新版本的 schema 变更(删列、改类型、数据迁移)会让旧版本代码无法工作。回滚流量不等于回滚数据——数据已经被新版本写坏了,切回 Blue 也没用。数据库变更必须保持“向前兼容”(只增列、不删列),或者配套独立的数据回滚方案,Blue-Green 才安全。

为何常见:只看到了环境隔离,忽略了数据是共享的。环境可以有两套,数据库往往只有一个。

误区认为回滚要重新跑 CI/CD 构建旧版本、重新发布到集群,耗时几十分钟甚至几小时。

正解渐进式交付的核心优势是“流量级回滚”——Blue-Green 一条切换指令秒级完成,Canary 把权重调回 0 即可。只有在 Blue 环境已被回收、无法切流量的情况下,才需要重新部署旧版本,此时的回滚时间会从秒级恶化到小时级。所以生产实践中始终强调:观察期结束前,旧环境要一直热着。

为何常见:习惯了传统“先卸载再装旧包”的发布方式,没有建立起“环境与流量分离”的思维模型。

面试题

Q1. 下列关于 Blue-Green 部署的描述,正确的是?

单选题 · easy

  • A.新旧版本并行,流量一次切换← 正确答案
  • B.新版本先给少量用户试用
  • C.原地覆盖旧版本直接升级
  • D.需要分多轮逐步放量验证

答案:A。Blue-Green 维护 Blue 和 Green 两套环境,正式发布时把流量一次性从旧版切到新版。B 和 D 描述的是 Canary 的渐进式放量,C 是传统的原地升级,都不符合 Blue-Green“双环境、一次性切换”的核心特征。

Q2. Canary 部署这个名称的由来是什么?

单选题 · easy

  • A.因为金丝雀飞行速度很快
  • B.源自矿工用金丝雀测毒气← 正确答案
  • C.因为金丝雀羽毛非常鲜艳
  • D.源自古代航海用鸟寻陆地

答案:B。旧时煤矿工人下井会带金丝雀,它对有毒气体极敏感,鸟一倒下人就立刻撤离。Canary 部署借用这个意象——先放少量流量“试毒”,新版本环境出了问题只影响小范围用户,像金丝雀一样充当预警信号。

Q3. 渐进式交付的核心目标是什么?

单选题 · easy

  • A.提升代码评审的整体速度
  • B.把新版本风险控制在最小← 正确答案
  • C.大幅降低开发人力成本
  • D.加快淘汰老旧版本系统

答案:B。渐进式交付的本质是风险控制——通过小范围验证、逐步放量、快速回滚,把发布事故的影响面压到最小。代码评审速度、人力成本、版本淘汰都不是它的核心目标。

Q4. Canary 放量中“10% 的流量”指的是什么?

单选题 · mid

  • A.新版本代码的 10% 被部署
  • B.10% 的流量访问到新版本← 正确答案
  • C.10% 的服务器运行新版本
  • D.10% 的测试用例被执行

答案:B。Canary 放量的百分比是“流量权重”——负载均衡器把 10% 的线上请求路由到新版本环境。不是部署 10% 的代码,也不是 10% 的服务器,而是 10% 的真实用户请求由新版本处理。

Q5. Blue-Green 部署相比传统发布的最大优势是什么?

单选题 · mid

  • A.极大节省服务器资源成本
  • B.回滚迅速只需一键切流量← 正确答案
  • C.减少代码变更与发布次数
  • D.发布过程无需任何自动化测试

答案:B。Blue-Green 最突出的优势是秒级回滚——旧环境始终在线,出问题只需把流量切回 Blue,不需要重新构建或部署。A 说反了,Blue-Green 恰恰要付出双倍资源成本;C、D 与部署策略无关。

Q6. 某团队的错误率基线为均值 1%、标准差 0.5%,放量期间错误率突然变为 3%,Z-score 约为多少?

单选题 · mid

  • A.约 2 倍标准差
  • B.约 4 倍标准差← 正确答案
  • C.约 6 倍标准差
  • D.约 8 倍标准差

答案:B。Z = (0.03 - 0.01) / 0.005 = 4。Z-score 衡量当前值偏离基线的程度,超过 3 就属于统计显著异常。这个计算过程跟火锅店差评率从 1% 涨到 3%、往日波动只有 0.5% 是同一个道理——4 倍波动,老张该警惕了。

Q7. Canary 放量到 50% 时监控发现错误率升到 8%(阈值 2%),正确的做法是?

单选题 · hard

  • A.继续放量到 100% 观察
  • B.立即回滚切回旧版本← 正确答案
  • C.忽略告警等待自动恢复
  • D.只回滚部分出错节点

答案:B。错误率 8% 远超阈值 2%,说明新版本存在严重缺陷,应立刻把放量比例调回 0,让全部流量回到旧版本,然后再定位问题。继续放量会扩大故障面,等待自动恢复是不负责任的赌博,部分回滚在流量粒度上难以操作。

Q8. 团队用 Blue-Green 部署且新旧版本共享数据库。新版本发布后出现数据错误,执行回滚(流量切回 Blue)但故障依旧,最可能的原因是?

单选题 · extreme

  • A.新版本写入了不兼容脏数据← 正确答案
  • B.Blue 环境被自动化脚本覆盖
  • C.流量实际没有切回旧版本
  • D.数据库连接池没有自动刷新

答案:A。新旧版本共享数据库时,新版本的 schema 迁移或数据写入可能已经污染了共享数据。回滚流量只解决了“代码执行者”的问题,却没解决“数据已被改坏”的问题——Blue 的旧代码读到脏数据照样报错。这是 Blue-Green 架构下最经典的“假回滚”陷阱。

Q9. 以下哪些属于渐进式交付的常用部署策略?

多选题 · mid

  • A.Blue-Green 双环境部署← 正确答案
  • B.Canary 渐进式部署← 正确答案
  • C.Waterfall 瀑布式交付
  • D.全量就地一次性发布

答案:AB。Blue-Green 和 Canary 是渐进式交付的两大核心策略,共同点是“旧环境热备、流量可控、可快速回滚”。Waterfall 是传统软件开发流程模型,全量就地发布是一次性替换,两者都没有渐进式风险控制能力。

Q10. 以下哪些是 Blue-Green 部署需要付出的代价?

多选题 · hard

  • A.需要双倍服务器资源成本← 正确答案
  • B.数据库变更需额外兼容处理← 正确答案
  • C.完全不支持快速回滚操作
  • D.维护期间新旧环境并行← 正确答案

答案:ABD。Blue-Green 的三大代价:双倍资源成本、共享数据库的兼容性挑战、新旧环境并行维护的运维开销。C 说反了,快速回滚恰恰是它最大的优势。理解代价才能正确选型——不是所有团队都付得起“双倍房租”的。