压测工具选型: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 的渲染,把机器资源吃掉了大半。

避坑指南:我曾经在分布式压测时,没注意 JMeter 主从节点的时区同步,结果聚合报告里的时间戳全乱了。后来我养成了一个习惯——压测前先 ntpdate 同步所有节点时间。
  • 优点:插件生态丰富、支持协议多、有图形化报告
  • 缺点:资源消耗大、单机并发上限有限(通常 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
小技巧:wrk 的 Lua 脚本里可以自定义请求体、处理响应、甚至控制请求频率。我曾经用它模拟过「先登录获取 token,再带着 token 访问业务接口」的场景,效果比 JMeter 轻量多了。
  • 优点:性能极高、资源占用极低、延迟统计精准
  • 缺点:只支持 HTTP/HTTPS、Lua 脚本学习曲线、无图形界面
  • 适合场景:接口基准测试、性能对比、快速定位性能瓶颈

4. ab —— 最轻量的「小刀」

ab 是 Apache 自带的工具,几乎每个 Linux 系统都有。它的用法简单到令人发指——一个命令就能跑起来。

但说实话,ab 的局限性也很明显。它不支持 Keep-Alive 连接复用,不支持参数化,不支持分布式。我见过有人用 ab 压测 RESTful API,结果因为每次请求都新建 TCP 连接,把服务器的连接数打爆了。

# ab 的基本用法
ab -n 10000 -c 100 http://localhost:8080/
注意:ab 的并发模型是「多进程 fork」,在 macOS 上 fork 的开销很大。我曾经在 MacBook 上用 ab 压测本地服务,并发 500 时机器直接卡死。后来换到 Linux 服务器上就正常了。
  • 优点:零安装、使用简单、适合快速验证
  • 缺点:功能单一、不支持复杂场景、性能一般
  • 适合场景:开发自测、简单接口的快速压测、临时验证

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 长连接压测

三、选型策略:到底怎么选?

我总结了一个「三问选型法」,你照着问自己就行:

  1. 问协议:被测系统是什么协议?如果是 HTTP 以外的协议(如 JDBC、FTP、MQ),直接选 JMeter。如果只是 HTTP,继续往下看。
  2. 问场景:是做基准测试还是复杂业务压测?基准测试用 wrk 或 ab,复杂业务用 Locust 或 JMeter。
  3. 问团队:团队里谁会写脚本?Python 好的人用 Locust,Java 好的人用 JMeter,运维同学用 wrk 或 Go-stress-testing。

我的推荐组合:

  • 日常开发自测:ab 或 wrk
  • 接口性能基准:wrk
  • 全链路压测:JMeter(分布式)
  • 自动化流水线:Go-stress-testing
  • 快速原型验证:Locust

四、写在最后

工具只是手段,不是目的。我见过有人花两周研究 JMeter 的插件,结果压测数据还是不准。也见过有人用 ab 跑了几分钟,就发现了接口的瓶颈。

记住一句话:压测工具选得对,问题排查快一倍。 选错了工具,你可能会被工具本身的问题误导,浪费大量时间。

嗯,今天就聊到这里。下一章我会讲如何搭建一个可复用的压测环境,包括监控、数据采集和报告生成。到时候见。