压测工具选型:JMeter、wrk、ab、Locust、Gatling 的对比与选型建议

做压测这么多年,我经常被问到同一个问题:「到底该用哪个工具?」

说实话,没有银弹。每个工具都有自己的脾气。我见过有人用 ab 测动态接口,结果数据完全不准。也见过团队用 JMeter 压一个简单的静态页面,折腾了半天配置。

今天我就把这几个主流工具掰开揉碎,讲讲它们的优缺点,以及我个人的选型经验。

先看一张图,理清思路

压测工具选型决策树 你的压测场景是什么? 简单接口/静态资源 ab (Apache Bench) wrk 复杂业务/多协议 JMeter Gatling 高并发/自定义场景 Locust 注:实际选型还需考虑团队技术栈、报告需求等因素

逐个拆解:每个工具的特点

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 接口,结果证书验证失败,折腾半天才发现是工具本身的问题。

注意:ab 只适合测静态资源或极简单的 GET 请求。别用它测 POST 接口或带 cookie 的会话。

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%。

小技巧:wrk 的 Lua 脚本里可以写多个请求,模拟用户浏览多个页面的场景。比如先登录,再访问首页,最后提交表单。

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 自己先挂了……

注意: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。

小技巧:Locust 可以配合 Docker 做分布式压测。每个 worker 跑一个容器,master 负责汇总数据。这样能突破单机瓶颈。

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,那上手会慢一些。

我的建议:如果你们团队有 Java/Scala 背景,而且对报表质量要求高,选 Gatling 准没错。我有个项目就是靠 Gatling 的报告说服了客户,说我们的系统能扛住 10 万并发。

选型建议:一张表说清楚

工具 适用场景 学习成本 并发能力 报告质量 我的推荐指数
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,再发请求,问题就解决了。所以,选对工具,事半功倍。

一句话总结:没有最好的工具,只有最适合你场景的工具。先搞清楚你的需求,再选工具,别反过来。

想要更多资料,联系可可