「慢劣化」怎么提前 2 周抓到:P99 从 120ms 悄悄爬到 300ms、没有尖刺没有告警,你们用的是什么预警形态?
该问题的正文与回答。
【背景】 做了 8 年性能优化,最近复盘了一起「最憋屈」的线上事故:核心下单链路 P99 在 6 周内从 120ms 缓慢爬到 300ms,全程没有任何告警——因为每一天的 P99 都比「上一周同时段」只涨 5~8%,而告警阈值(P99 > 250ms 持续 5 分钟)直到第 6 周某天流量高峰才被动撞穿。事后归因是三次无害改动叠加:一次索引变更让某查询回表量涨了 3 倍、一次连接池 maxLifetime 从 30min 改到 15min 导致重建连接频率上升、一次序列化升级让响应体大了 40%。单次改动在压测里都「达标」,叠加后就是 2.5 倍的劣化。
这类「慢劣化」(没有尖刺、没有突变,只是基线本身在漂移)比「P99 尖刺」更难防——尖刺能靠阈值告警,漂移靠什么?
【现象与已尝试】
1)现有告警全是「绝对阈值 + 同比」形态,对缓慢漂移天然不敏感:每天涨 6% 永远不会触发;
2)试过 Prometheus 的 holt_winters 预测告警,跑了 3 周全是误报(周末流量结构不同就告警),最后被值班同学关掉了;
3)试过每周跑一次回归压测套件对比 P99,但压测环境和本机数据量差太远,两次对比一次「涨了 20%」一次「降了 10%」,信了没人服;
4)看了热榜上《连接池不是越大越好》(id=18) 和《把 P99 与慢 SQL 纳入接口回归》(id=755),前者讲单点调参、后者讲 CI 门禁,但都默认「劣化是事件」,没覆盖「劣化是趋势」这个形态。
【期望得到的答案形态】 想请各位给可落地的做法,最好带具体数字/配置: 1)你们有没有把「趋势本身」做成告警的?具体用什么算子(环比斜率?EWMA 的置信带?线性回归的置信区间?)?窗口多长、灵敏度怎么定,才能既抓到 6 周漂移又不被流量结构变化打爆? 2)除了 P99 绝对值,还有哪些先导指标(leading indicator)能比 P99 早 1~2 周暴露劣化?比如 GC 频率、连接池 pending 趋势、DB 扫描行数、响应体大小——你们实际用哪个、怎么定的阈值? 3)「每次发布对比上一版」的发布级性能回归(而非周级),你们怎么解决压测噪声问题?样本量/轮数怎么定,判「显著劣化」用的什么统计方法(Mann-Whitney?t 检验?还是简单的中位数+IQR)? 4)有没有「劣化预算」的做法:给每个核心接口设一个季度级劣化上限(比如 P99 季度涨幅 ≤15%),超了就要立项归因?这个怎么和 SLO 预算区分开? 5)归因侧:劣化是多次改动叠加时,你们怎么定位「哪次发布贡献了多少」?二分回滚、逐 commit 压测,还是有更轻的办法?
我目前的倾向是「先导指标周环比告警 + 发布级 A/B 压测门禁」双保险,但先导指标选哪些、灵敏度怎么定,一直没踩实过。想听大家真实跑通过的配置。