3、常用工具介绍:wrk、ab、JMeter、Locust、Gatling 的优缺点对比
做吞吐测试这么多年,我摸过的工具少说也有七八个。每个工具都有自己的脾气,选对了事半功倍,选错了……嗯,我有一回用错工具压测一个长连接服务,折腾了两天数据全是废的。今天我把最常用的五个工具掰开揉碎讲给你听。
3.1 wrk:轻量级压测利器
wrk 是我个人最常用的快速验证工具。它基于 C 语言 + Lua 脚本,单机就能压出几十万的 QPS。
核心优势:
- 资源占用极低,一台 4C8G 的机器就能压出 10 万+ QPS
- 支持 Lua 脚本定制请求逻辑,比如签名、参数拼接
- 内置毫秒级延迟统计,p99/p999 一目了然
我在项目中遇到过一个问题:用 wrk 压测一个登录接口,发现 p99 延迟从 50ms 飙到了 800ms。排查了半天,原来是 Lua 脚本里每次请求都重新加载了 RSA 密钥文件。改成全局加载后,延迟直接降回 60ms。你看,工具本身没问题,脚本写得不讲究照样翻车。
我的使用习惯:快速验证用 wrk,配合 -d 30s -t 4 -c 100 这种参数,30 秒就能拿到初步结论。但注意,wrk 不支持分布式,单机瓶颈明显。
3.2 ab:Apache 的老牌工具
ab(Apache Bench)是很多新手入门的第一个压测工具。说实话,我现在基本不用它了,但架不住它简单——一条命令就能跑。
ab -n 10000 -c 100 http://example.com/api
但你要小心,ab 有几个硬伤:
- 只支持 HTTP/1.0 和简单的 HTTP/1.1,对 HTTPS 支持很差
- 无法模拟复杂的请求流程,比如先登录再下单
- 统计信息过于简陋,只有平均延迟和吞吐,没有百分位延迟
避坑指南:我曾经用 ab 压测一个 HTTPS 接口,结果工具自己 SSL 握手就占了 80% 的时间,压出来的数据完全不能反映真实性能。后来换成 wrk 才拿到准确数据。
3.3 JMeter:功能最全的“瑞士军刀”
JMeter 是我做复杂场景压测的首选。它支持 HTTP、JDBC、JMS、FTP 等几十种协议,还能通过插件扩展。
说实话,JMeter 的 GUI 界面第一次打开时我有点懵——按钮太多了。但用顺手之后,你会发现它的逻辑很清晰:
- 线程组控制并发模型
- 取样器定义请求类型
- 监听器收集结果数据
- 断言验证响应正确性
我个人最常用的功能:
- 参数化:用 CSV 文件驱动不同用户数据
- 关联:从上一个响应中提取 token 传给下一个请求
- 分布式压测:一台 Master 控制多台 Slave 同时施压
但 JMeter 也有缺点。它的 GUI 模式本身就很吃资源,我试过在 GUI 下开 500 个线程,结果 JMeter 自己先卡死了。记住,压测时一定要用命令行模式:
jmeter -n -t test.jmx -l result.jtl -e -o report/
3.4 Locust:Python 工程师的最爱
Locust 是我见过最“程序员友好”的压测工具。你用 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 search(self):
self.client.post("/search", {"q": "test"})
你看,代码可读性很强。@task 后面的数字表示权重,3 意味着 search 被执行的频率是 index 的 3 倍。这种设计很符合真实用户行为——不是每个用户都只访问首页。
我的经验:Locust 的 Web UI 很漂亮,实时显示 RPS、响应时间、失败率。但要注意,它的 Master-Slave 模式在压测大量并发时,网络通信会成为瓶颈。我曾经用 10 台 Slave 压 5 万并发,结果 Master 节点 CPU 跑满了,数据采集延迟了十几秒。
3.5 Gatling:高性能的 Scala 选手
Gatling 用 Scala 写测试脚本,底层基于 Akka 的 Actor 模型,性能非常强悍。它的报告是我见过最漂亮的——HTML 格式,包含活跃连接数、响应时间分布、吞吐量趋势等十几个图表。
但说实话,Gatling 的学习曲线有点陡。如果你不会 Scala,写一个简单的 GET 请求都要查半天文档。不过一旦上手,你会发现它的 DSL 很优雅:
val scn = scenario("BasicSimulation")
.exec(http("request_1")
.get("/api/users")
.check(status.is(200)))
.inject(atOnceUsers(100))
Gatling 的独特优势:
- 异步非阻塞 IO,单机并发能力远超 JMeter
- 内置断言机制,可以自动判断压测是否通过
- 报告自带性能瓶颈分析,比如哪个请求拖慢了整体延迟
3.6 横向对比:一张表说清楚
我整理了一个对比表格,方便你根据场景选工具:
| 维度 | wrk | ab | JMeter | Locust | Gatling |
|---|---|---|---|---|---|
| 开发语言 | C + Lua | C | Java | Python | Scala |
| 单机并发能力 | 极高 | 中等 | 中等 | 较高 | 极高 |
| 协议支持 | HTTP/HTTPS | HTTP | 几十种协议 | HTTP/HTTPS | HTTP/HTTPS |
| 脚本复杂度 | 低 | 极低 | 中等 | 低 | 高 |
| 分布式支持 | 不支持 | 不支持 | 支持 | 支持 | 支持 |
| 报告质量 | 命令行输出 | 命令行输出 | HTML 报告 | Web 实时 | HTML 报告 |
| 学习成本 | 低 | 极低 | 中等 | 低 | 高 |
3.7 我的选型建议
你想想看,选工具其实就是在选“匹配度”:
- 快速验证接口性能:wrk,30 秒出结果,不废话
- 教学演示或简单测试:ab,一条命令搞定
- 复杂业务场景压测:JMeter,插件生态最丰富
- 团队全员 Python:Locust,代码即脚本,维护成本低
- 追求极致性能和报告:Gatling,就是学习曲线陡了点
最后提醒一句:不管选哪个工具,压测前一定要确认“压测工具本身不是瓶颈”。我见过有人用 JMeter GUI 压 1000 并发,结果 JMeter 自己先 OOM 了。记住,工具是手段,不是目的。
这张决策树图是我自己画的,每次给团队做技术选型时都会拿出来用。你顺着左边的分支走,基本不会选错工具。
一个小技巧:如果你不确定选哪个,先用 wrk 跑一轮快速验证。如果 wrk 的数据显示接口没问题,那大概率是工具配置问题。如果 wrk 都压不上去,再换 JMeter 或 Gatling 做深度分析。
想要更多资料,联系可可