基本信息
阅读时间:约 15 分钟
字数:约 5813 字
摘要:灰度上线的难点不在放量,而在看什么、看到哪一步就停。本文提出「五阈一线」:错误率、尾延迟、饱和度、业务代理、客户端现场五个观测面,加一条三段式回滚线,配 DORA 量级数据、2012 年做市商部署事故、四个可测指标与一周落地清单。
全文语音
中文
English
日本語
한국어
晚上十一点二十,南京软件大道边上的一栋写字楼还亮着半层灯。陈默把笔记本合上又打开,屏幕右下角的监控面板上,一条红线正在匀速往上爬。那是新版本的错误率曲线,十二分钟前刚切到百分之五的流量。
「我们不是没看指标,」他后来跟我说,「我们看的是错误率。错误率从零点二涨到零点三,涨得还挺有礼貌,谁都以为再等十分钟就回去了。」
那天他们等了四十分钟。等到客服群里出现第一张截图,一位用户在支付页面反复点了七次;等到有人终于说出「回滚吧」,已经是凌晨零点四十。窗外那场雨停了,楼下便利店的灯也灭了。
第二天复盘,白板上写了三行字:错误率有阈值,延迟没有;业务指标有人报,客户端崩溃没人看;所有人都盯着面板,没有人敢说回滚。这三行字,就是这篇文章要讲的事——灰度上线真正难的不是放量,而是你到底看什么、看到什么程度就该停。
专业分析:五个阈值不是仪表盘,是一条判定链
先把量级摆出来。DORA 每年发布的工程效能报告,样本量级为万人级从业者(来源类型:跨年度问卷统计,具体数值逐年浮动)。其中一个稳定结论是:高绩效团队的变更失败率大致在百分之五上下,低绩效团队常在百分之三十到四十;两者差的不是写代码的能力,而是「变更之后多久知道它坏了」。Google 的站点可靠性实践文档把这件事拆成两个动作:先定义什么叫「可接受的坏」,再定义「坏到什么程度必须停」(来源类型:公开工程实践手册,非对照实验)。

可多数团队只把「坏」定义成一个数:错误率。这就是问题的起点。我把这套东西命名为「五阈一线」:五个阈值——错误率、尾延迟、饱和度、业务代理指标、客户端现场;一条回滚线——三段判定。它不是把面板堆得更满,而是一条判定链:每个阈值都带着自己的分母、观察窗和责任人,最后汇到同一个不需要开会就能执行的结论上。

它和传统做法的差别可以列成一张表。传统做法是单指标门禁:守住一个错误率,涨了就回滚,没涨就放量。五阈一线是五个观测面加一条判定规则:任何一个面失守都有明确的动作,任何一个面都没失守也不必再靠感觉拖延。前者像只装了一个烟雾报警器的房间,后者是烟雾、温度、电流、水压、门磁五路一起接进同一块面板。

真实案例值得掰开看。2012 年 8 月 1 日,美国一家做市商给交易系统上线新代码,部署到八台服务器中的七台,剩下一台仍在跑一段本该被替换掉的旧逻辑。开盘后四十五分钟,那台服务器持续发出错误订单,公司当天损失约四亿四千万美元(来源类型:监管披露与公开复盘),第二年即被收购。所有技术复盘里最刺眼的一句不是「代码有 bug」,而是「没有任何一项部署后的观察指标能把新旧不一致这件事显出来」。灰度单元本身不一致,是观察清单的第一类盲区。
所以清单里要有可数的度量。四个数就够:变更失败率(本期导致回滚或热修的发布数除以总发布数)、MTTD(从指标越线到有人确认的分钟数)、回滚决策时长(从确认到按下按钮的中位数)、灰度逃逸率(未经灰度拦截直接进入全量的缺陷数除以期内缺陷总数)。四个数都不需要采购工具,一张周表、每周十分钟就能记下来。
执行清单也一并列出,共五条:一,每个阈值写清分子、分母与排除项;二,硬阈与软阈分开,硬阈不需要请示;三,每个观察窗配对最小样本量,不只看时长;四,指定唯一的回滚决策人及其备份;五,每次灰度结束记一行逃逸记录。下面九节,就是把这张清单一条条拆开讲。
第一阈:错误率要带分母,否则等于没看
陈默他们的面板上写着「错误率 0.3%」,看着很稳。他事后才发现,那个数的分母是「网关收到的全部请求」,其中将近三成是健康检查、内部探针和监控心跳。把这些剔掉之后,真实用户请求的错误率其实已经接近百分之一点二,是阈值的两倍多。

灰度阶段的分母尤其容易失真。切百分之一的流量,十分钟可能只有几百个请求;在两百个请求上,零点五个百分点的差异只对应一个错误。样本这么小的时候,曲线抖一下不代表什么,抖四下也可能什么都不代表——但值班的人会先被吓到,然后开始「再观察观察」。

所以口径要写死三件事:分子是什么(只算 5xx,还是把业务失败码、超时、主动断开都算进来),分母是什么(请求数、会话数还是下单次数),排除项有哪些(探针、内部调用、压测流量、爬虫)。这三件事不写清楚,两个团队看同一块面板会得出两个结论,然后花半小时争论谁的数字对。

写法上建议用「绝对加相对,取更严者」:绝对阈值零点五个百分点,相对阈值是过去七天同时段基线的两倍。为什么要有相对项?因为有的服务基线本来就是零点零二,翻倍也才零点零四,用绝对值去卡它等于永远不报警;反过来,基线本来就高的老服务,绝对阈值又会天天误报。
最后是归属。口径必须落到一个人头上——通常是 SRE 或质量负责人——由他维护这张定义表,任何人改口径都要在发布单上留一行记录。灰度是跨团队动作,但口径不能是投票产物,否则每次出事都要先开一场关于定义的会。
第二阈:平均延迟骗人,尾延迟才代表用户
陈默团队那晚还有一块面板是绿的:平均响应时间一百二十毫秒,和上一周几乎一样。可同一时间,P99 已经从四百毫秒爬到九百毫秒。平均值没动,是因为绝大多数请求确实还快;被拖慢的那百分之一,正好是走了新链路的那批用户。

尾延迟为什么先坏?因为排队。新版本多加了一次下游调用,单次只多几毫秒,但在高峰期,连接池一满,请求就开始排队;排队会让慢的更慢,快的仍然快,于是均值稳如老狗,尾部已经翻倍。再加上客户端超时重试,一次慢请求会变成三次,把尾部进一步推高。

阈值的写法要具体到分位和持续时间:P99 相对基线上升百分之二十,或绝对值超过八百毫秒,持续五分钟即视为越线;P95 作为辅助观察,不单独触发。为什么要加持续时间?单分钟的尖刺多半是流量毛刺或一次 GC,连续五分钟才是趋势。

还有一层拆分不能省:整体 P99 会掩盖单接口的崩坏。一次灰度里,整体 P99 只涨了三十毫秒,看起来无害;拆到接口级别才发现,查询订单列表这个接口的 P99 从三百毫秒涨到了二点一秒,而它只占流量的百分之四。按接口、按地域、按调用方各拆一层,才能看见这种局部塌方。
有个团队的做法值得抄:发布评审的第一屏只放两个数,接口级 P99 和错误率,其余指标折叠在下面。理由很朴素——评审时间只有二十分钟,人的注意力放在哪里,事故就往哪里躲。
第三阈:饱和度是唯一能提前报警的指标
错误率和延迟都是「已经坏了」的信号,饱和度是「快坏了」。队列在积压、连接池占用在爬、CPU 的等待时间在变长、磁盘 IO 排着队——这些数在用户还没感觉到疼的时候就先动了,它们是清单里唯一带预测性的部分。

灰度真正的价值也在这里:它给了你一个小规模的饱和试验场。百分之一的流量压在同样的实例规格上,资源占用的斜率可以按比例外推;如果百分之一的流量就让连接池占用从三成涨到五成,那么全量之后它会碰到天花板,只是时间问题。

阈值建议按资源类型分别写:单实例 CPU 使用率超过百分之七十并持续十分钟;数据库连接池占用超过百分之八十;消息队列积压量的增长速度连续三个采样点为正且斜率上升;磁盘 IO 等待超过百分之二十。这几条都不需要精密模型,取的是「还来得及」的那一刻。
这里有个容易忽略的细节:斜率比绝对值重要。同样是百分之六十的 CPU,一条是平的,一条是十分钟涨十五个点,后者才是危险信号。所以面板上最好同时画绝对值和一阶差分,值班的人看斜率,不用心算。
协同上还有一条:容量评估要和发布同步做,不能等发布完再扩容。扩容本身是一次变更,两次变更叠在一起,出了问题连归因都做不了。把「本次发布需要多少余量」写进发布单,是跨团队最容易达成共识的一行字。
第四阈:业务指标天生滞后,用代理指标顶上
支付成功率、下单转化率这类指标,从用户按下按钮到数据落进报表,常常隔着几分钟到几小时:埋点有批量上报,数仓有调度窗口,风控有异步复核。等这条曲线掉下来,事故往往已经跑完半程。所以业务阈不能直接盯终值,要盯它的上游。

代理指标的做法是把业务动作拆成几段可即时观测的环节:下单页到支付页的跳转率、支付接口的成功回调数、错误码分布的变化、客服工单里关键词的频次。这几项都是分钟级可见的,任何一项偏离基线,都意味着终值大概率要掉。

阈值可以这样写:下单成功率相对基线下降一个百分点;支付回调失败率超过百分之零点八;同一类错误码在十分钟内出现超过五十次。第一条给业务方看,后两条给研发看,同一份清单、两个视角,避免各说各话。
关键是责任人。业务阈必须由业务方签字确认,并由业务侧的值班人负责观察,不能只挂在研发的面板上。原因很实际:研发看不出「转化率下降一个百分点」对一个正在做活动的品类意味着什么,业务方一眼就知道那是灾难还是噪音。
有个反例值得记住。一次灰度里,业务大盘纹丝不动,但客服工单里「重复扣款」这个词的频次在四十分钟内涨了四倍。当时没人把它当指标,因为它不在面板上。后来复盘,那才是最早的信号——比任何一条曲线都早二十分钟。
第五阈:客户端现场,服务端看不见的那一半
服务端一切正常,用户端白屏——这是灰度里最常见也最难查的一类事故。因为在服务端眼里,请求都成功了;问题出在返回的数据结构、字段长度、图片地址,或者某个只有老机型才会走的分支上。第五阈存在的意义,就是把这一半补上。

要看的数有三个:崩溃率(按会话维度算,不按设备)、首屏失败率或白屏率、以及「静默失败」——接口返回了错误但页面没有任何提示,用户只看到转圈。第三个数最难拿,通常要靠客户端埋点主动上报兜底逻辑的触发次数。

这些数能不能用,取决于分群能力。灰度必须能按版本号、机型、系统版本、地域切片,否则第五阈等于没有:整体崩溃率零点二,可能是一个小机型版本崩到百分之八,被大盘平均掉了。分群维度要在灰度方案里提前写死,事后再补是来不及的。
阈值建议:崩溃率超过百分之零点三,或相对基线翻倍;首屏 P95 超过二点五秒;静默失败上报数超过基线三倍。三条里任一触发,按硬阈处理,直接停止放量。
协同上有一条硬规定:客户端与服务端的灰度批次必须绑定同一个观察窗。否则最常见的场景是——客户端团队在等后端确认「接口没问题」,后端在等客户端确认「崩溃不是我们引起的」,两边都在等对方先出事,四个小时就过去了。
回滚线:三段判定,把「要不要回」变成不用争论的事
回到陈默那个晚上。那四十分钟里,真正花在排查上的不到十分钟,剩下三十分钟都花在争论:这个涨幅算不算异常、要不要再等一个数据点、回滚会不会影响第二天的活动。没有一条事先写好的判定线,讨论就只能靠嗓门和职级。

第一段是硬线:五个阈里的硬性项——错误率绝对阈值、崩溃率、支付回调失败率——任一越线,值班人直接执行回滚,不需要请示,也不需要拉会。硬线的意义不是严谨,是把决策从「讨论」降级成「执行」,省下的正是最贵的那三十分钟。

第二段是软线:两个以上软性阈值同时越线,并持续十分钟,触发回滚。软阈包括尾延迟、饱和度、业务代理指标的轻度偏离。单个软阈越线很常见,不值得停;两个同时越线,说明不是噪音,是同一个原因在两个面上冒头。
第三段是人线,也是最容易被忽略的一段:值班人在十五分钟内无法判定「这是不是问题」,默认回滚。这条规则反直觉,但它把不确定性本身变成了触发条件。灰度期最怕的不是判断错,是没人敢判断;默认回滚等于给犹豫设了一个出口。
回滚本身也要练。建议每季度做一次游戏日:人为注入一个已知故障,从「曲线报警」开始计时,到「流量归零、指标回稳」结束,记录总时长。目标中位数十分钟以内。第一次做通常会超过四十分钟,因为会暴露一堆平时想不到的问题——回滚脚本权限不在值班人手上、旧版本镜像被清理了、数据库迁移不可逆。
最后是文化。回滚不是失败,是机制在工作。复盘时不要问「谁决定回滚的」,要问「哪个阈值本该提前报警却没报」。前一个问题会让人下次更不敢按按钮,后一个问题会让清单变准。
观察窗口:放量节奏和观察时长要配对
最常见的错误不是阈值定错,而是观察窗太短:百分之一的流量看五分钟,曲线还没抖完就放到百分之二十五。五分钟里可能只过来几十个请求,任何统计判断都不成立,等于用一个噪声样本给全量背书。

所以观察窗的第一原则是看样本量,不是看时间。低峰期的一小时,请求量可能还不如高峰期十分钟;用固定时长去卡,会在低峰期过度自信、在高峰期过度保守。规则可以写成:每个批次至少积累 N 个请求(按服务量级定,常见是每个批次不少于一千)或 M 个错误事件,取先到者。

节奏建议这样 pairing:百分之一或单实例,观察不少于三十分钟,且必须覆盖一次业务高峰的开始段;百分之五,观察不少于两小时;百分之二十五,观察一个自然日;百分之五十,观察一个完整业务周期,包含一次结算或对账。越往上,观察的不是技术指标,而是业务节奏带来的副作用。
窗口内必须有人真的在看。设一个「守望人」的角色:他在窗口内只负责看数,不做别的开发任务,不参加会议。这个角色听起来奢侈,实际成本很低——它把「大家顺便看一眼」变成「有人负责」,而事故恰恰发生在所有人都以为别人在看的时候。
窗口结束要留结论,三选一:通过、延长、回滚。写进发布单,写清延长多久、等什么信号。没有结论的观察窗等于没开过——下一批放量时,没人记得上一批到底看到了什么。
三种走偏的做法
第一种走偏,是各团队各看一套。研发看错误率,业务看成交额,客户端看崩溃率,三块屏挂在三个群里,没有一张共同的表。表面上人人有指标,实际上没有一条判定链:错误率没动,业务在掉,谁都说自己那面是绿的。灰度是跨团队动作,清单必须先统一,再看细分。

第二种走偏,是指标齐全却没人盯。面板做得像驾驶舱,二十个图、六种颜色,观察窗里所有人都去开另一个会了。等有人想起来刷新,已经过了两个小时。指标的价值不在于存在,而在于有人在窗口内为它负责——这就是守望人这个角色存在的理由。

第三种走偏,是把回滚当失败。谁回滚谁写检讨,绩效里记一笔,于是所有人都学会「再等等」。等成了习惯,硬线就形同虚设,因为按下按钮的人要先掂量自己的处境。这种走偏最隐蔽,它不会体现在任何一张面板上,只会体现在回滚决策时长的中位数里——那个数会悄悄从十分钟涨到四十分钟。
三种走偏有个共同点:都把灰度当成一个技术动作,而不是一次跨团队的约定。技术动作只需要工具,约定需要口径、责任人和默认规则。工具可以一周买齐,约定要花一个季度养成。
跨团队落地:一周把清单跑起来
周一,定口径。一页纸,五个阈值各自的分子、分母、排除项,谁维护、改了口径在哪里登记。这一页纸不需要完美,需要的是所有人看的是同一页。

周二,定阈值与回滚线,业务方签字。硬阈三条、软阈两条、人线一条,写清数字和持续时间。签字这个动作看着形式,实际是提前把「出事时谁承担」这件事谈完。

周三,指定角色。守望人、回滚决策人、备份,三个名字写进值班表。同一个人不能既当守望人又当发布执行人,因为看数和操作本来就需要两个视角。
周四,跑一次真实的小流量灰度。重点不是发布本身,是计时:MTTD 多少、决策多久、回滚多久。第一次的数会难看,把它记下来,它就是你后面四周的基线。
周五,复盘逃逸记录,只改一个数——最不灵的那条阈值。一次改五个,下次出事你分不清是哪个改动起了作用。四周之后,你会有一条自己的变更失败率曲线,那条曲线比任何行业基准都可靠。
灰度不是把风险摊薄,而是把「什么时候该停」提前写好,然后让按下按钮这件事不需要勇气。
常见问题
1.问:团队只有五六个人,没有专职 SRE,五个阈值是不是太多了?答:先做三个——带分母的错误率、接口级 P99、一条硬回滚线。这三个能覆盖八成事故;等这三条稳定跑满一个月,再补饱和度和客户端现场。
2.问:阈值到底定多少才合适?答:用自己过去四周同一时段的基线,不要照抄行业数字。先按「绝对加相对、取更严者」写,跑两周看误报率;误报超过三成就是太紧,一次没报就是太松,一次只调一档。
3.问:业务指标波动本来就大,怎么避免误回滚?答:用代理指标替代终值,并加两个约束——相对基线而非绝对值,连续十分钟而非单点。单点越线只记录,不触发。业务阈的签字人负责判断「这次波动是不是活动带来的」。
4.问:回滚之后发现只是配置写错了,下次怎么更快?答:把配置也纳入灰度单元,配置变更走同一套观察窗;同时把「配置回滚」和「镜像回滚」分成两个脚本,各自单独演练一次,别等到出事才发现配置回滚要重走审批。
5.问:守望人要求人在窗口内一直看数,团队扛不住怎么办?答:先让告警兜住硬阈,人只需要处理软阈和判断。另外把观察窗排进正常排班,而不是加班;一个窗口两小时,一周两次,比所有人全天候盯着更可持续。
图片来源:图1 DarkoStojanovic / Pixabay (CC0) · 图2 AS_Photography / Pixabay (CC0) · 图3 osmnblqn / Pixabay (CC0) · 图4 jonathansautter / Pixabay (CC0) · 图5 Stevebidmead / Pixabay (CC0) · 图6 Ray_Shrewsberry / Pixabay (CC0) · 图7 Activedia / Pixabay (CC0) · 图8 garten-gg / Pixabay (CC0) · 图9 Fxq19910504 / Pixabay (CC0) · 图10 Pexels / Pixabay (CC0) · 图11 Kranich17 / Pixabay (CC0) · 图12 Beto_MdP / Pixabay (CC0) · 图13 Dennis / Pixabay (CC0) · 图14 sasint / Pixabay (CC0) · 图15 Scottslm / Pixabay (CC0) · 图16 Matthias_Groeneveld / Pixabay (CC0) · 图17 Alexas_Fotos / Pixabay (CC0) · 图18 Alexas_Fotos / Pixabay (CC0) · 图19 torstensimon / Pixabay (CC0) · 图20 Alexas_Fotos / Pixabay (CC0) · 图21 reallywellmadedesks / Pixabay (CC0) · 图22 reallywellmadedesks / Pixabay (CC0)
本文为信息分享与方法论科普,不构成任何专业建议,请结合自身情况判断。
本文由 AI 生成,经人类主编终审。

评论(0)