4、性能回归对比工具:JMeter对比模式、wrk与ab的对比用法、Locust的对比测试
性能回归对比,说白了就是「改完代码,系统变快还是变慢了?」。这个问题,我几乎每次上线前都要问自己一遍。
你可能会想,跑一遍压测不就行了?嗯,没那么简单。环境波动、网络抖动、GC停顿……这些干扰因素会让单次结果很不靠谱。所以我们需要专门的对比工具和方法。
今天我就聊聊我常用的四类工具:JMeter、wrk、ab 和 Locust。它们各有脾气,也各有妙用。
4.1 JMeter 对比模式:别只跑一次
JMeter 大家都很熟,但很多人拿它做对比测试时,犯过一个低级错误——只跑一轮就下结论。
我个人习惯的做法是:至少跑 3 轮,取中位数。为什么不是平均值?因为平均值容易被极端值带偏。中位数更稳。
具体操作上,JMeter 提供了两种对比思路:
- 命令行非 GUI 模式:用
-n -t参数跑,结果存成 jtl 文件。然后对比两次的 jtl 文件。 - 使用 Comparison Report:JMeter 5.0 之后有个插件叫「Comparison Report」,可以直接把两次结果叠在一起看。
我举个例子。假设你要对比优化前后的接口延迟:
# 优化前
jmeter -n -t test_plan.jmx -l before.jtl
# 优化后
jmeter -n -t test_plan.jmx -l after.jtl
# 然后用 Comparison Report 插件加载两个 jtl 文件
JMeter 的对比报告会给出每个百分位的延迟变化。我重点关注 P99 和 P999。这两个值最能反映系统的「长尾」问题。
举个例子,有一次我优化了一个缓存逻辑,平均延迟从 50ms 降到了 30ms,但 P99 反而从 200ms 涨到了 500ms。这就是典型的「平均好看了,但尾巴更长了」。如果只看平均值,你就会被骗。
4.2 wrk 与 ab:轻量级对比利器
wrk 和 ab 都是命令行工具,适合快速验证。它们不像 JMeter 那么重,但胜在简单直接。
ab(Apache Bench) 是最老牌的压测工具。它的用法很简单:
ab -n 10000 -c 100 http://your-api.com/endpoint
但 ab 有个硬伤——它只支持 HTTP/1.0,而且不支持 Keep-Alive 的复用。这意味着它的结果往往比实际偏慢。我一般只用它做「快速冒烟测试」,不会拿它做精细对比。
wrk 就好多了。它支持 HTTP/1.1,还能用 Lua 脚本定制请求。我个人更偏爱 wrk。
wrk -t12 -c400 -d30s http://your-api.com/endpoint
这个命令的意思是:12 个线程,400 个并发连接,持续 30 秒。
wrk 的输出里,我最关注的是 Requests/sec 和 Latency 的分布。特别是 Std Dev(标准差),如果这个值很大,说明系统不稳定。
-t(线程数)和 -c(连接数)完全一致。我曾经犯过一个错,优化前用 -t4 -c100,优化后用了 -t8 -c100,结果吞吐量翻倍了,我还以为是优化有效……后来才发现是线程数变了。
我整理了一个对比表,方便你快速选择:
| 工具 | 协议支持 | 并发模型 | 适合场景 | 我的评价 |
|---|---|---|---|---|
| ab | HTTP/1.0 | 单线程 | 快速冒烟 | 够用,但别太信它 |
| wrk | HTTP/1.1 | 多线程 + epoll | 精细对比 | 我的首选 |
| JMeter | HTTP/1.1 + 自定义 | 线程池 | 复杂场景 | 功能最强,但重 |
| Locust | HTTP/1.1 + 自定义 | 协程(gevent) | 脚本化对比 | 灵活,但学习成本高 |
4.3 Locust 的对比测试:用代码控制一切
Locust 跟前面几个工具不太一样。它用 Python 写测试脚本,可以精确控制每个用户的行为。对于复杂的业务场景,比如「先登录、再下单、再支付」,Locust 就比 wrk 和 ab 强太多了。
做对比测试时,Locust 的 Web UI 可以实时看到两个版本的曲线。但我个人更习惯用 无头模式(headless),然后对比 CSV 报告。
# 优化前
locust -f locustfile.py --headless -u 100 -r 10 --run-time 5m --csv=before
# 优化后
locust -f locustfile.py --headless -u 100 -r 10 --run-time 5m --csv=after
然后我会写一个简单的 Python 脚本,把 before_stats.csv 和 after_stats.csv 里的关键指标拉出来对比。
Locust 还有一个好处:你可以用 @task 装饰器定义不同权重的任务。比如 70% 的请求是查询,30% 是写入。这样对比出来的结果更贴近真实业务。
我曾经在一个项目中,用 Locust 对比了「同步写入」和「异步写入」两种方案。同步方案的平均延迟是 120ms,异步方案是 15ms。但异步方案在 P99 上偶尔会飙到 2 秒。这就是典型的「异步换吞吐,但牺牲了稳定性」。如果没有 Locust 的精细对比,我可能就盲目上线了。
4.4 核心逻辑:对比测试的流程
说了这么多工具,其实对比测试的核心逻辑就三步:
- 基线建立:在「优化前」跑一轮,记录所有关键指标。
- 变量控制:只改你要验证的那个变量(比如代码、配置、硬件),其他全部保持不变。
- 结果对比:用同一个工具、同一个脚本、同一个环境,跑第二轮,然后对比。
下面这张图是我自己总结的对比测试流程,你可以参考:
嗯,这张图基本概括了我做对比测试的整个思路。你照着这个流程走,基本不会出大问题。
最后说一句:工具只是手段,对比的逻辑才是核心。不管你用 JMeter、wrk、ab 还是 Locust,只要控制好变量、跑够样本、关注 P99,你就能得到可信的结论。
想要更多资料,联系可可