压测工具选型:JMeter、wrk、Locust、ab、Go-stress-testing 对比与选型策略
做性能压测这么多年,我经常被问到同一个问题:「到底该用哪个工具?」
说实话,没有银弹。每个工具都有自己的脾气。你想想看,用菜刀切西瓜和用水果刀削苹果,能是一回事吗?
今天我就把这几个主流工具掰开揉碎了讲。JMeter、wrk、Locust、ab、Go-stress-testing,它们各自擅长什么,坑在哪里,什么时候该选谁。
一、先看一张全景图
这张图是我自己画的。你看,五个工具分布在不同的象限。有的偏重功能全面,有的偏重性能极致。选型其实就是做取舍。
二、逐个拆解:每个工具的真实面目
1. JMeter —— 压测界的「瑞士军刀」
JMeter 是我用得最久的工具。说实话,它什么都好,就是太重了。
优点:
- 图形化界面,拖拽式配置,新手友好
- 插件生态极其丰富。想测啥协议都有现成的
- 支持分布式压测,能撑起大规模场景
- 报告功能强大,聚合报告、图形结果一应俱全
缺点:
- 资源消耗大。我曾经在 8C16G 的机器上跑 500 并发,JMeter 自己先卡死了
- 脚本维护麻烦。改一个参数要翻好几层菜单
- 启动慢,每次打开都要等半天
我的经验: JMeter 适合做复杂业务场景的压测,比如多接口串联、参数化、断言校验。但别用它测纯高并发,你会后悔的。
2. wrk —— 轻量级「性能怪兽」
wrk 是我个人最爱的工具之一。它用 C 语言写的,底层基于 epoll/kqueue,性能极其强悍。
优点:
- 单机就能压出几十万 QPS
- 资源消耗极低。我试过在 2C4G 的云服务器上跑 10 万并发,CPU 才用了 30%
- 支持 Lua 脚本,可以做简单的请求定制
缺点:
- 只支持 HTTP 协议
- 没有 GUI,全是命令行
- 报告简陋,只有几个核心指标
注意: wrk 的 Lua 脚本能力有限,别指望用它做复杂的业务逻辑。它就是个「纯打流」的工具。
3. Locust —— 程序员的最爱
Locust 是用 Python 写的。它的设计理念很特别——用代码定义用户行为。
优点:
- 纯 Python 编写,可编程性极强
- 支持分布式,天然适合大规模压测
- Web 界面实时查看结果,体验不错
缺点:
- Python 的 GIL 锁限制了单机并发能力
- 性能不如 wrk 和 Go-stress-testing
- 学习曲线陡峭,需要会写 Python
我的建议: 如果你的团队都是 Python 开发者,Locust 是首选。我曾经用它模拟 2000 个用户同时登录下单,脚本写起来非常顺手。
4. ab (Apache Bench) —— 老古董但够用
ab 是 Apache 自带的压测工具。它简单到令人发指,但也简陋到令人发指。
优点:
- 安装即用,不用配置
- 命令简单,一行搞定
- 适合快速验证
缺点:
- 只能测 HTTP/HTTPS
- 不支持分布式
- 并发能力弱,超过 10000 并发就吃力
- 报告信息太少
避坑指南: 我曾经用 ab 压一个 API,结果 ab 自己先挂了。后来才发现它默认的并发模型是 fork 进程,开太多进程直接把系统资源耗尽了。所以,ab 只适合做「冒烟测试」。
5. Go-stress-testing —— 后起之秀
这个工具是用 Go 写的。Go 的协程模型天生适合做压测。
优点:
- 基于协程,单机并发能力极强
- 支持 HTTP、WebSocket、gRPC 等多种协议
- 安装简单,一个二进制文件搞定
- 报告清晰,有实时 QPS 和延迟分布
缺点:
- 社区较小,文档不够完善
- 不支持分布式(目前)
- 脚本能力有限
我的体验: 这个工具我最近用得比较多。有一次需要压测 WebSocket 长连接,JMeter 配置起来太麻烦,wrk 又不支持。Go-stress-testing 一行命令搞定,真香。
三、核心对比:一张表说清楚
| 维度 | JMeter | wrk | Locust | ab | Go-stress-testing |
|---|---|---|---|---|---|
| 语言 | Java | C | Python | C | Go |
| 单机并发能力 | 中等(5万左右) | 极高(50万+) | 较低(1万左右) | 低(5000左右) | 高(30万+) |
| 协议支持 | 极丰富 | 仅HTTP | HTTP + 扩展 | 仅HTTP | HTTP/WS/gRPC |
| 脚本复杂度 | GUI拖拽 | Lua脚本 | Python代码 | 命令行参数 | 命令行参数 |
| 分布式支持 | ✅ 原生支持 | ❌ 不支持 | ✅ 原生支持 | ❌ 不支持 | ❌ 不支持 |
| 报告质量 | ★★★★★ | ★★☆☆☆ | ★★★★☆ | ★★☆☆☆ | ★★★☆☆ |
| 学习成本 | 低(GUI) | 中(命令行) | 高(需Python) | 极低 | 低 |
| 资源消耗 | 高 | 极低 | 中 | 低 | 低 |
四、选型策略:什么时候用哪个?
我总结了一套选型逻辑,你照着套就行:
- 场景一:复杂业务压测(多接口、参数化、断言)
→ 选 JMeter。别犹豫,它的 GUI 和插件生态无人能敌。 - 场景二:纯高并发打流(测 QPS 天花板)
→ 选 wrk 或 Go-stress-testing。我一般用 wrk,因为它的 Lua 脚本够用且性能极致。 - 场景三:团队都是 Python 开发者
→ 选 Locust。代码即配置,版本管理方便,还能做 CI/CD 集成。 - 场景四:快速验证、冒烟测试
→ 选 ab。一行命令搞定,适合开发自测。 - 场景五:WebSocket 或 gRPC 压测
→ 选 Go-stress-testing。JMeter 配置太麻烦,wrk 不支持,这个刚刚好。
核心原则: 别用一个工具打天下。我自己的工具箱里,JMeter、wrk、Go-stress-testing 三个常备。不同场景换不同工具,这才是专业做法。
五、实战演示:用 wrk 压一个 API
光说不练假把式。我拿 wrk 举个例子,看看实际怎么用。
# 基本用法:压 30 秒,12 个线程,400 个连接
wrk -t12 -c400 -d30s http://api.example.com/users
# 带 Lua 脚本:模拟 POST 请求
wrk -t4 -c200 -d60s -s post.lua http://api.example.com/login
# post.lua 内容示例
wrk.method = "POST"
wrk.body = '{"username":"test","password":"123456"}'
wrk.headers["Content-Type"] = "application/json"
你看,就这么几行。跑完之后会输出:
Running 30s test @ http://api.example.com/users
12 threads and 400 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 45.23ms 12.34ms 198.76ms 78.90%
Req/Sec 7,234.56 1,234.56 12,345.67 85.67%
217,036 requests in 30.00s, 28.45MB read
Requests/sec: 7,234.53
Transfer/sec: 0.95MB
重点关注 Latency 和 Req/Sec。如果延迟的 P99 超过 200ms,说明系统扛不住了。
小技巧: 压测时记得先跑一轮「预热」,让 JIT 编译和连接池都稳定下来。我一般会先跑 10 秒,然后看正式数据。
六、避坑指南:我踩过的那些坑
- 我曾经用 JMeter 压 1000 并发,结果 JMeter 自己 OOM 了。 后来发现是 GUI 模式太吃内存。记住:生产环境压测一定要用
jmeter -n -t命令行模式。 - 我曾经用 ab 压 HTTPS,结果全是 SSL 错误。 后来才知道 ab 对 HTTPS 的支持很弱,建议用 wrk 替代。
- 我曾经用 Locust 压 5000 并发,结果 CPU 100%。 原因是 Python 的 GIL 锁导致多线程效率低下。解决方案是用
--processes参数启动多进程。 - 我曾经用 wrk 压 WebSocket,结果 wrk 不支持。 嗯,这个坑我踩得最冤。后来换了 Go-stress-testing 才搞定。
好了,工具选型就讲到这里。记住一句话:没有最好的工具,只有最合适的工具。 你根据场景选,准没错。
总结: JMeter 适合复杂业务,wrk 适合纯高并发,Locust 适合 Python 团队,ab 适合快速验证,Go-stress-testing 适合现代协议。选型时重点看:并发能力、脚本复杂度、分布式支持、报告质量、学习成本。
想要更多资料,联系可可