压测工具选型:JMeter、wrk、ab、Locust、Gatling 的对比与选型建议
做压测这么多年,我经常被问到同一个问题:「到底该用哪个工具?」
说实话,没有银弹。每个工具都有自己的脾气。我见过有人用 ab 测动态接口,结果数据完全不准。也见过团队用 JMeter 压一个简单的静态页面,折腾了半天配置。
今天我就把这几个主流工具掰开揉碎,讲讲它们的优缺点,以及我个人的选型经验。
先看一张图,理清思路
逐个拆解:每个工具的特点
1. ab (Apache Bench)
这玩意儿太老了。我记得刚入行那会儿,大家都用 ab 测 Nginx 性能。它的优点就一个:简单。
一条命令就能跑起来:
ab -n 10000 -c 100 http://example.com/
但缺点也很明显。它只支持 HTTP/0.9 和 HTTP/1.0,对 HTTP/1.1 的支持很有限。更别提 HTTP/2 了。我在项目中遇到过用 ab 测 HTTPS 接口,结果证书验证失败,折腾半天才发现是工具本身的问题。
2. wrk
wrk 是我个人比较喜欢的工具。它基于 Lua 脚本,可以自定义请求逻辑。而且性能极高,单机就能压出几十万 QPS。
举个例子,你想模拟用户登录后的操作:
wrk -t12 -c400 -d30s --script=login.lua http://example.com
Lua 脚本里可以写:
wrk.method = "POST"
wrk.body = '{"username":"test","password":"123"}'
wrk.headers["Content-Type"] = "application/json"
嗯,这里要注意:wrk 的学习曲线比 ab 陡一点。但一旦上手,你会发现它真的很灵活。我曾经用它压过一个实时推荐系统,单机压到 5 万 QPS,CPU 才用了 60%。
3. JMeter
说到 JMeter,很多人的第一反应是「太重了」。确实,它启动慢,吃内存,GUI 界面有时候卡得让人抓狂。
但你不能否认,它是功能最全的。支持 HTTP、HTTPS、JDBC、JMS、FTP……几乎你能想到的协议它都支持。而且有丰富的插件生态。
我建议这样用 JMeter:
- 脚本录制:用 Badboy 或 JMeter 自带的 HTTP 代理录制器,快速生成脚本
- 参数化:用 CSV Data Set Config 读取测试数据
- 断言:加 Response Assertion 检查返回结果
- 监听器:用 Aggregate Report 或 Summary Report 看结果
但说实话,JMeter 的 GUI 模式只适合调试。真正跑压测的时候,一定要用命令行模式:
jmeter -n -t test.jmx -l result.jtl -e -o report/
这样能省不少资源。我在项目中遇到过有人用 GUI 跑 1000 并发,结果 JMeter 自己先挂了……
HEAP="-Xms4g -Xmx8g"
4. Locust
Locust 是 Python 写的。如果你团队里 Python 用得多,那它是个不错的选择。
它的核心思想是「每个用户是一个协程」。你可以用 Python 代码定义用户行为:
from locust import HttpUser, task, between
class WebsiteUser(HttpUser):
wait_time = between(1, 5)
@task
def index(self):
self.client.get("/")
@task(3)
def about(self):
self.client.get("/about")
你看,代码很直观。而且 Locust 的 Web UI 做得不错,可以实时看到 RPS、响应时间、失败率等指标。
我个人觉得 Locust 最大的优势是可编程性。你可以写复杂的用户行为逻辑,比如模拟用户浏览商品、加入购物车、下单、支付。这在 JMeter 里得配一堆元件,在 Locust 里几行代码就搞定了。
但缺点也有:单机并发能力不如 wrk。毕竟 Python 的协程再快,也比不上 C 写的 wrk。
5. Gatling
Gatling 是 Scala 写的,但你不一定非得会 Scala。它提供了一套 DSL,写起来有点像写代码:
val scn = scenario("BasicSimulation")
.exec(http("request_1")
.get("/"))
.pause(5)
setUp(
scn.inject(atOnceUsers(100))
).protocols(http.baseUrl("http://example.com"))
Gatling 的报表是我见过最漂亮的。它自动生成 HTML 报告,包含响应时间分布、吞吐量、活跃连接数等图表。你想想看,给老板汇报的时候,直接甩一个 Gatling 报告,比 Excel 表格有说服力多了。
不过 Gatling 的学习成本比 JMeter 高。如果你的团队里没人熟悉 Scala 或 Java,那上手会慢一些。
选型建议:一张表说清楚
| 工具 | 适用场景 | 学习成本 | 并发能力 | 报告质量 | 我的推荐指数 |
|---|---|---|---|---|---|
| ab | 简单 GET 请求、静态资源 | ★☆☆☆☆ | ★★☆☆☆ | ★☆☆☆☆ | 2/5 |
| wrk | 高并发、自定义请求逻辑 | ★★☆☆☆ | ★★★★★ | ★★☆☆☆ | 4/5 |
| JMeter | 复杂业务、多协议、分布式 | ★★★★☆ | ★★★☆☆ | ★★★★☆ | 3/5 |
| Locust | Python 团队、复杂用户行为 | ★★★☆☆ | ★★★☆☆ | ★★★☆☆ | 3/5 |
| Gatling | Java/Scala 团队、高质量报表 | ★★★★☆ | ★★★★☆ | ★★★★★ | 4/5 |
我的最终建议
别纠结。先想清楚你要压什么:
- 测 Nginx 或 CDN:用 wrk,简单高效
- 测业务接口,有登录、下单等复杂流程:用 JMeter 或 Gatling
- 团队全是 Python 工程师:用 Locust,代码即脚本
- 只是临时看一眼接口性能:用 ab,一条命令搞定
我曾经犯过一个错:用 ab 去压一个带 Token 验证的接口,结果压了半天全是 401。后来换成 wrk,写了个 Lua 脚本先拿 Token,再发请求,问题就解决了。所以,选对工具,事半功倍。
想要更多资料,联系可可