压测工具选型:JMeter、Locust、wrk、ab、Go-stress-testing 对比与选型策略
做压测这么多年,我经常被问到同一个问题:「到底该用哪个工具?」
说实话,没有银弹。每个工具都有自己的脾气。我见过有人用 ab 测长连接接口,结果数据完全不准。也见过团队用 JMeter 做千兆级压测,界面卡到怀疑人生。
今天我把主流工具掰开揉碎讲清楚。你听完就知道,什么场景该拿哪把刀。
一、工具速览:一句话说清各自定位
| 工具 | 核心定位 | 语言 | 协议支持 |
|---|---|---|---|
| JMeter | 企业级全功能压测平台 | Java | HTTP/HTTPS/FTP/JDBC/WebService… |
| Locust | Python 开发者友好的可编程压测 | Python | HTTP/HTTPS(可扩展自定义协议) |
| wrk | 高性能 HTTP 基准测试 | C(Lua 脚本扩展) | HTTP/HTTPS |
| ab | Apache 自带的最简压测工具 | C | HTTP/HTTPS |
| Go-stress-testing | Go 语言实现的轻量压测工具 | Go | HTTP/WebSocket/gRPC |
二、逐个拆解:每个工具我都踩过坑
1. JMeter —— 压测界的瑞士军刀
JMeter 功能是真的全。图形界面拖拽就能写脚本,断言、参数化、关联、监听器一应俱全。我在项目中用它做过数据库压测、消息队列压测,甚至 FTP 上传下载的压测。
但说实话,它也有明显的短板。我记得有一次压测一个高并发 WebSocket 服务,JMeter 的线程模型在 2000 并发时就开始抖动。后来排查发现,Java 的线程开销加上 GUI 的渲染,把机器资源吃掉了大半。
- 优点:插件生态丰富、支持协议多、有图形化报告
- 缺点:资源消耗大、单机并发上限有限(通常 3000-5000 线程)、脚本维护成本高
- 适合场景:企业级全链路压测、多协议混合场景、需要复杂断言和参数化的场景
2. Locust —— Python 党的最爱
Locust 的核心理念是「代码即脚本」。你写一个 Python 类,定义用户行为,然后框架帮你管理协程。我个人很喜欢这种模式,因为调试起来特别方便。
不过要注意,Locust 默认使用协程(gevent),不是真正的多线程。这意味着如果你的被测服务有阻塞 I/O 操作,协程的优势就体现出来了。但如果是 CPU 密集型的接口,协程反而帮不上忙。
实战经验:我曾在一次电商大促压测中,用 Locust 模拟 5000 用户同时浏览商品详情页。脚本里加了随机等待时间和商品 ID 参数化,效果非常好。但后来想压测支付接口时,发现 Locust 对 HTTPS 长连接的支持不如 wrk 稳定。
- 优点:脚本灵活、分布式扩展简单、Web UI 实时监控
- 缺点:协程模型不适合所有场景、协议扩展需要自己写代码
- 适合场景:快速原型验证、Python 技术栈团队、需要频繁修改压测逻辑的场景
3. wrk —— 性能压测的「法拉利」
wrk 是我个人最常用的基准测试工具。它用 C 语言编写,基于 epoll/kqueue 事件驱动,单机就能轻松打出几十万 QPS。
你想想看,一个命令行工具,几行 Lua 脚本就能实现参数化、请求构造、结果统计。而且它的输出非常清晰——延迟分布、吞吐量、请求失败率一目了然。
# 一个简单的 wrk 压测命令
wrk -t12 -c400 -d30s --latency http://localhost:8080/api
# 带 Lua 脚本的复杂场景
wrk -t4 -c200 -d60s -s script.lua http://localhost:8080
- 优点:性能极高、资源占用极低、延迟统计精准
- 缺点:只支持 HTTP/HTTPS、Lua 脚本学习曲线、无图形界面
- 适合场景:接口基准测试、性能对比、快速定位性能瓶颈
4. ab —— 最轻量的「小刀」
ab 是 Apache 自带的工具,几乎每个 Linux 系统都有。它的用法简单到令人发指——一个命令就能跑起来。
但说实话,ab 的局限性也很明显。它不支持 Keep-Alive 连接复用,不支持参数化,不支持分布式。我见过有人用 ab 压测 RESTful API,结果因为每次请求都新建 TCP 连接,把服务器的连接数打爆了。
# ab 的基本用法
ab -n 10000 -c 100 http://localhost:8080/
- 优点:零安装、使用简单、适合快速验证
- 缺点:功能单一、不支持复杂场景、性能一般
- 适合场景:开发自测、简单接口的快速压测、临时验证
5. Go-stress-testing —— 后起之秀
这个工具是 Go 语言写的,天生就带着 Go 的并发优势。它支持 HTTP、WebSocket、gRPC 三种协议,而且编译后是单个二进制文件,部署极其方便。
我记得有一次需要在 CI/CD 流水线里集成压测,JMeter 太重,wrk 的 Lua 脚本不好维护。最后选了 Go-stress-testing,一个 YAML 配置文件搞定所有参数,完美融入自动化流程。
# 命令行用法
go-stress-testing -c 100 -n 10000 -u http://localhost:8080/api
# 配置文件方式(适合自动化)
go-stress-testing -c config.yaml
- 优点:部署简单、并发性能好、支持 WebSocket/gRPC
- 缺点:社区较小、文档不够完善、扩展性有限
- 适合场景:CI/CD 集成、微服务压测、WebSocket 长连接压测
三、选型策略:到底怎么选?
我总结了一个「三问选型法」,你照着问自己就行:
- 问协议:被测系统是什么协议?如果是 HTTP 以外的协议(如 JDBC、FTP、MQ),直接选 JMeter。如果只是 HTTP,继续往下看。
- 问场景:是做基准测试还是复杂业务压测?基准测试用 wrk 或 ab,复杂业务用 Locust 或 JMeter。
- 问团队:团队里谁会写脚本?Python 好的人用 Locust,Java 好的人用 JMeter,运维同学用 wrk 或 Go-stress-testing。
我的推荐组合:
- 日常开发自测:ab 或 wrk
- 接口性能基准:wrk
- 全链路压测:JMeter(分布式)
- 自动化流水线:Go-stress-testing
- 快速原型验证:Locust
四、写在最后
工具只是手段,不是目的。我见过有人花两周研究 JMeter 的插件,结果压测数据还是不准。也见过有人用 ab 跑了几分钟,就发现了接口的瓶颈。
记住一句话:压测工具选得对,问题排查快一倍。 选错了工具,你可能会被工具本身的问题误导,浪费大量时间。
嗯,今天就聊到这里。下一章我会讲如何搭建一个可复用的压测环境,包括监控、数据采集和报告生成。到时候见。