一个运行了7年的支付系统,日志里没有任何报错,监控面板一片绿色。但用户投诉率却从每月3起涨到了47起。工程师Sergey Vinickiy在复盘时发现,系统的成功率是99.9%——听起来很高,意味着每1000笔交易就有1笔失败。对于日活百万的平台,这是每天1000个愤怒的用户。

可靠性问题的诡异之处在于:它不会主动敲门。

产品bug会被客服工单追着跑,性能瓶颈会让服务器报警尖叫。但成功率从99.95%掉到99.5%?监控可能安静得像深夜的机房。Vinickiy把这比作"慢性失血"——系统表面健康,内里却在一点点流失用户信任。他所在的团队曾用三个月追踪一个"偶发超时",最终发现是某个下游服务的重试策略在特定流量模式下触发了连锁反应。这个问题存在了两年,从未触发任何告警阈值。

四个信号里,只有两个在认真干活

四个信号里,只有两个在认真干活

谷歌提出的"四个黄金信号"(延迟、流量、错误、饱和度)是业界通用框架。Vinickiy的观察很直接:可靠性工作主要集中在错误和延迟两个维度。流量和饱和度更多指向容量规划,而真正的用户体验崩塌,往往始于一个被忽略的500错误,或一次突然飙到8秒的响应延迟。

他分享了一个具体案例。某次大促期间,系统的错误率始终低于0.1%,看起来稳如老狗。但深入分析后发现,这部分错误集中在创建订单的关键路径上——用户点了"立即购买",页面转圈10秒后报错。从技术指标看,这是"可接受的波动";从业务视角看,这是直接把用户送给竞争对手。

SLI(服务等级指标)和SLO(服务等级目标)的设定因此变得微妙。Vinickiy团队曾把"API成功率"设为SLI,目标99.9%。后来改成"关键用户旅程成功率",同样的系统,评分从A直接掉到C。因为注册、下单、支付这些核心链路,和"获取用户头像"这类边缘接口,在用户体验里根本不是一回事。

为什么好系统会偷偷变坏

为什么好系统会偷偷变坏

Vinickiy用了一个很产品经理的比喻:系统像一间住久了的房子。新功能是一块块新家具,可靠性是地基和管道。你不断往里搬东西,却从不检查下水道有没有堵。三年后一次暴雨,才发现阳台早就渗水了。

他的团队做过一次"可靠性审计",遍历了所有运行超过18个月的服务。结果发现,73%的服务存在至少一个"已知但低优先级"的故障模式——某个依赖的超时设置不合理,某个降级开关从未被验证过,某个日志打印语句在极端流量下会成为瓶颈。单独看都不是问题,组合起来就是生产事故的原材料。

更隐蔽的是依赖漂移。A服务调用B服务,最初设计时B的P99延迟是50ms,A设置了200ms超时。两年后B的架构变了,P99变成150ms,A的超时没动。数字上一切正常,但容错空间被压缩了三分之二。一次B的短暂抖动,就让A的线程池打满,进而拖垮C、D、E。

定期"体检"比救火划算

定期"体检"比救火划算

Vinickiy的核心建议很朴素:给可靠性工作留出固定时间。不是等故障复盘,而是主动做"可靠性评审"——像代码审查一样审查系统的容错设计。他的团队每季度会选一两个核心服务,模拟依赖故障、验证降级逻辑、检查超时和重试策略是否合理。

一个反直觉的发现是:越是"稳定"的老系统,越需要这种审查。新系统有设计文档,工程师还记得当时的权衡。老系统的知识随着人员流动逐渐散失,变成"别碰,能跑就行"的黑箱。Vinickiy见过最极端的案例:一个核心支付接口的降级逻辑,在代码里存在了4年,从未被触发过——因为触发条件里的一个参数名,早在3年前就被改掉了。

这种审查的另一个价值是建立"故障预算"思维。SLO不是数字游戏,是团队达成共识的"可接受损失额度"。这个季度错误预算还剩多少?如果快用完了,是暂停发版还是接受降级?Vinickiy说,这种对话能把可靠性从"运维的锅"变成"全队的决策"。

文章结尾,Vinickiy放了一张截图:他们最近一次可靠性评审后,主动下调了两个服务的SLO目标——因为分析发现,为了维持过高的承诺,团队把30%的精力花在了对用户体验无感知的"优化"上。他写道:「有时候,承认"足够好"比追求"完美"更需要勇气。」

你的系统上次"可靠性体检"是什么时候?如果今晚核心依赖挂掉,你确定那些降级开关真的能用吗?