本层判断标准

这次改动后,基准负载下的 P95 与上一次相比变化了多少毫秒?

答不出数字,说明没有基线。先按固定负载模型跑一次并存档——第一次压测只做存档,不设通过与否;有了基线,第二次才谈退化。

性能判的是什么

「感觉挺快」不是判据,带负载条件的数字才算。先把负载条件写死——并发数、数据量、请求分布、机器规格、预热多久后统计多久——再让脚本按它跑;条件一变,前后两次的数字就没有可比性。

P95 延迟
< 300ms
门禁比的就是这一个数,相对上次退化超过 20% 即失败。
P99 延迟
< 800ms
长尾在这里现形。平均值看不出来,用户感觉得到。
吞吐
≥ 200 rps
单实例。低于这个数先扩实例,再谈优化。
错误率
< 0.5%
超过即视为这次压测结果不可用。

前置条件写在一起:上面这几个数对应单实例、2 核 4G、数据库同机的前提,前提变了整套数都要重跑。它不进三类判断里的任何一类——别的检查判对错,它判变化。

长什么样子

一份性能报告是「负载条件 + 几个百分位 + 跟上次的差」。它判的是变化,不是对错。

一份性能报告

提交 a1b2c3d   单实例 2C4G   并发 50   预热 60s / 统计 300s
  P95  287ms(上次 241ms,+19%)
  P99  742ms      吞吐 214rps      错误率 0.1%
结论:达标;本次让 P95 变差 19%

要认的是这个形状:负载条件与提交号写在报告里,结论写明让哪一项变差了多少。只写「有优化」等于没写。

助手交出来的样子

提交 a1b2c3d   单实例 2C4G   并发 10(上次 50)
              预热 10s / 统计 60s(上次 300s)
  P95  132ms(上次 241ms,-45%)
结论:达标;本次优化 45%

认它的办法:负载条件变了,数字就不可比。并发、统计时长、实例规格任何一项与上次不同,这份报告等于没跑。把上一次的数字删掉只留本次,同样是这个效果——没有基线就没有趋势。

典型应用示例:一次查询改动之后

场景:助手给列表接口加了一个联表字段。接口测试全绿,功能没问题,改动合并了。

有它 合并前跑一次基准压测,P95 从 118 毫秒变到 405 毫秒,退化超过 20%,改动被拦下。附带信息里有上一次的数字,看得出是这次加的联表引起的,回到实现层改写法而不是调阈值。
没有它 功能测试全绿就合了。上线后高峰期接口变慢,排查时这次改动已经和另外三次混在一起,没人知道是哪一次拖慢的——而最后一次能确认「一切正常」的时间点在一个月前。

基本注意点

每次压测至少十几分钟,算不进日常门禁,所以只在改到那几类地方时跑;压错一次会浪费半天,还会得出一个不能用的结论。

情况跑不跑为什么
改了查询或数据访问路径跑这一类退化最隐蔽,功能测试看不出来
新增了循环里的远程调用跑循环里查库、发请求、读文件都会改变延迟分布
改了缓存或批量策略跑失效范围与批量大小直接影响百分位
要上线了跑在接近生产的配置下跑一次,结果附进发布记录;没跑就写「未压」
功能测试还没绿不跑压的是一个会出错的行为,百分位没有意义
还没定判据,想先跑一遍看看不跑看到数字之后再定标准,标准一定会被数字迁就
在开发机或共享机器上压不跑数字既不可比也不可复现,同机服务还会被拖慢
数据集只有手搓的几十行不跑压不出循环查询与全表扫描,那是数据量到了才现形的问题

容量估算回答的是另一个问题:「要几台、留多少余量」。它按压测得出的单实例能力推算,前提(峰值、单条大小、日增量)写进同一份文档;前提变了就重算并替换,不留两套数字。不达标就调低阈值,属于改判据,要走单独的合并请求。

负载模型与阈值写进压测脚本,不写在报告里靠人看;结果落盘进仓库,下一次才有比较对象。每次运行要留下三个百分位、吞吐、错误率、当时的提交号与环境规格——缺一样,这个数字就不能引用。门禁里只保留一条硬检查:相对上次退化超过 20% 即失败。