2、性能基准测试:基准测试的意义、常用工具、测试场景设计、结果解读与报告
聊性能优化,第一件事不是动手改代码。
而是先搞清楚——系统现在到底什么水平?
这就是基准测试的意义。说白了,你得先有个“起点”,才能知道后面优化了多少。没有基准,你改完代码说“快了”,快了多少?是心理作用还是真有效?没人知道。
2.1 基准测试到底在测什么
基准测试不是压力测试,也不是负载测试。它的目标很单纯:在可控条件下,测量系统的核心性能指标。
我个人习惯把基准测试分成两类:
- 单机基准:测一台机器的极限,比如一个API接口能扛多少QPS
- 对比基准:改前改后各跑一次,看差异
我在项目中遇到过最典型的场景:客户说系统慢,但运维说服务器负载不高。两边吵起来。我上去跑了个基准测试,发现接口响应时间在200ms到5秒之间剧烈抖动。嗯,问题找到了——不是负载高,是抖动大。这就是基准测试的价值,用数据说话。
核心指标就三个:
- 吞吐量(TPS/QPS)——每秒能处理多少请求
- 响应时间(RT)——平均、P50、P90、P99
- 错误率——超过某个阈值就算失败
2.2 常用工具:选对工具,事半功倍
工具这东西,没有最好的,只有最顺手的。我三个都用过,说说我的感受。
2.2.1 JMeter
JMeter 是重型武器。图形界面,插件丰富,能测HTTP、数据库、gRPC甚至JMS。适合复杂场景,比如多步骤事务、参数化、断言。
但说实话,它有点重。启动慢,跑大规模测试时本身就很吃资源。我一般用它做复杂业务流程的基准测试。
# JMeter 命令行模式(非GUI)
jmeter -n -t test_plan.jmx -l results.jtl -e -o report_dir
我的习惯:GUI只用来调试脚本,真正跑测试一定用命令行。否则JMeter自己就把机器吃满了,测出来的数据不准。
2.2.2 wrk
wrk 是我个人最常用的工具。轻量、高效,用Lua脚本可以做一些定制。它基于事件驱动,单机就能压出很高的并发。
适合快速验证接口性能,或者做简单的对比测试。
# 基本用法:10个线程,100个连接,持续30秒
wrk -t10 -c100 -d30s http://localhost:8080/api/hello
# 带Lua脚本的自定义测试
wrk -t4 -c200 -d60s -s custom.lua http://localhost:8080/api/order
你想想看,一条命令就能看到吞吐量和延迟分布,多方便。我曾经在排查一个缓存优化效果时,就是靠wrk前后各跑一次,30秒出结论。
2.2.3 ab(Apache Bench)
ab 是最古老的工具之一。简单到极致,一条命令就能跑。但它功能也少,不支持复杂的场景,而且对HTTPS支持不太好。
我一般只在临时验证时用它,比如刚部署完,随手测一下接口通不通、响应快不快。
# 1000个请求,10个并发
ab -n 1000 -c 10 http://localhost:8080/api/hello
注意:ab 的并发模型是阻塞式的,并发数高了以后,它自己反而会成为瓶颈。别用它测高并发场景,数据会骗人。
2.3 测试场景设计:别瞎测,要有章法
工具选好了,接下来就是设计场景。这一步很多人会忽略,直接对着接口一顿猛压。结果呢?数据出来了,但不知道代表什么。
我建议按这个思路来:
- 明确被测对象:是单个接口?还是整个链路?还是数据库?
- 确定负载模型:恒定并发?阶梯递增?还是模拟真实用户行为?
- 设定阈值:响应时间超过多少算失败?错误率容忍上限是多少?
- 预热:先跑几分钟,让JIT、连接池、缓存都稳定下来
- 正式测试:至少跑5分钟,数据才有统计意义
一个典型的基准测试场景模板:
| 参数 | 值 |
|---|---|
| 测试接口 | POST /api/order/create |
| 并发用户数 | 50 |
| 持续时间 | 5分钟 |
| 预热时间 | 1分钟 |
| 成功标准 | P99 < 500ms, 错误率 < 0.1% |
我曾经犯过一个错:没做预热,直接跑测试。结果前两分钟数据特别差,后面慢慢变好了。我还以为是系统不稳定,折腾了半天,其实是JIT还没生效。从那以后,预热成了我的固定流程。
2.4 结果解读:别只看平均数
数据出来了,怎么看?
很多人只看平均响应时间。这是个大坑。平均时间会把异常值抹平,让你觉得系统还不错。实际上呢?可能有一半的请求都超时了。
我习惯看这几个指标:
- P50:一半请求在这个时间以内,代表典型体验
- P90:90%的请求在这个时间以内,代表大多数用户
- P99:99%的请求在这个时间以内,代表最差的那1%用户
- 最大响应时间:偶尔看一眼,但别太在意,可能是GC抖动
我的经验:如果P99比P50高出10倍以上,说明系统有严重的抖动问题。这时候别盯着平均时间看,去查GC日志、慢查询、或者线程池排队情况。
2.5 报告输出:让数据会说话
基准测试的最终产出是一份报告。报告不是扔一堆数字就完事了,而是要讲清楚:
- 测了什么
- 怎么测的
- 结果是什么
- 结论是什么
我一般用JMeter的HTML报告,或者自己写脚本生成图表。关键是要把对比数据放上去。比如优化前P99是800ms,优化后是200ms,一眼就能看出效果。
# 一个简单的报告模板结构
1. 测试概述(目的、环境、工具版本)
2. 测试场景(接口、并发、时长、阈值)
3. 结果数据(吞吐量、响应时间分布、错误率)
4. 对比分析(如果有前后对比)
5. 结论与建议(是否达标、下一步优化方向)
避坑指南:我曾经在报告里只写了平均响应时间,结果被领导质疑“为什么用户还是说慢?”后来加上P99数据,才发现原来有5%的请求卡了2秒多。从那以后,我的报告里一定会有百分位数据。
好了,基准测试这部分就聊到这。记住一句话:没有基准的优化,都是耍流氓。下一章我们聊聊怎么从日志和监控里找到性能瓶颈,那才是真正动手的地方。