【背景】 我是做测试开发的,最近半年在推「性能回归门禁」:每次发版前跑一轮压测,把 P99 和上一版本对比。结果发现一个尴尬的事——同一个服务、同一台机器、同样的压测脚本,两次跑出来的 P99 能差 2~5ms,而且方向不固定。有一次 P99 从 42ms 变成 45ms,我提了回归缺陷,开发同学直接怼回来:「你自己再跑一次试试,说不定就回来了。」
他是对的。我复跑了 3 次,P99 分别是 41 / 45 / 42ms。那次「抖动」不是回归,是噪声。 但反过来的风险更可怕:如果真有一次 42 → 48ms 的实质退化,我怎么证明它不是噪声?
【常见的几种做法】
- 拍脑袋阈值:「P99 波动 10% 以内算正常」。简单,但 10% 对 P99=12ms 的接口是 1.2ms,对 P99=500ms 的接口是 50ms,噪声分布完全不在一个量级上。
- 固定绝对值阈值:「波动超过 5ms 才算退化」。对大延迟接口太松,对小延迟接口又太紧,而且 5ms 这个数从哪来?
- 多次取均值:跑 5 次取平均。能压住单次毛刺,但 5 次压测的时间成本 ×5,CI 里跑不动。
- 统计检验:对两组延迟样本做 Mann-Whitney U 检验 / t 检验,看 P 值。理论上最优雅,但「样本量多大才够」「P 值定 0.05 还是 0.01」这些参数本身又是一次拍脑袋。
- 看 P99 的置信区间:用 bootstrap 重采样算 P99 的 95% CI,两个版本的 CI 不重叠才算退化。方向对,但计算量和解释成本都不低。
【我的倾向】 我目前倾向「基线噪声带 + 显著性双门槛」:
- 先用同一版本连续跑 N 次(N 由 CI 时间预算决定,通常 3~5 次),算出 P99 的版本内噪声带(比如 IQR 或 95% CI);
- 新版本 P99 必须同时满足:(a) 超出基线噪声带,(b) 相对基线中位数偏移超过一个绝对下限(比如 1ms,防止小延迟接口被纯统计波动误报);
- 两个条件都满足才提回归缺陷,否则标记为「观察项」进周报。
理由:单靠统计检验会在小延迟接口上产生大量假阳性(12ms 的接口 1ms 波动就 P<0.01 了),单靠绝对值又会在大延迟接口上漏掉真实退化。双门槛本质上是「统计显著 + 业务可感知」的交集。
但我不确定的是:这个噪声带该用 P99 的分布算,还是该用「每次压测的 P99 值」的分布算? 前者样本量大但每个样本不是独立观测(同一次压测里的请求共享 GC / 连接池状态),后者样本量小但每次压测是一个独立实验。这个问题我还没想透。
【想听大家在什么场景下怎么选】
- 你们线上有性能回归门禁吗?判定标准是什么?谁定的、什么时候定的?
- 压测环境不稳定(共享集群 / 云 VM)和压测环境稳定(专用机器 / 裸金属)下,你们的噪声带差多少?
- 「P99 抖动 3ms」这件事,你们团队里有没有一个书面的、可复现的判定标准?还是每次靠资深同学拍板?
- 如果回归判定本身引入 3 倍压测时长,你们愿意付这个成本吗?
我猜大多数团队的答案是「没有,靠人看」。想看看大家的具体做法和踩坑,尤其是「噪声带到底怎么算、样本量怎么定」这块。
0赞
0收藏
0楼层