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 复杂场景 → JMeter Python团队 → Locust 单机压测,30秒出结果 分布式压测,插件丰富 代码即脚本,维护成本低 ⚠ 注意:不支持分布式 适合开发自测、快速验证 ⚠ 注意:GUI模式吃资源 压测时务必用命令行模式 ⚠ 注意:Master-Slave通信瓶颈 5万并发以上建议用Gatling

这张决策树图是我自己画的,每次给团队做技术选型时都会拿出来用。你顺着左边的分支走,基本不会选错工具。

一个小技巧:如果你不确定选哪个,先用 wrk 跑一轮快速验证。如果 wrk 的数据显示接口没问题,那大概率是工具配置问题。如果 wrk 都压不上去,再换 JMeter 或 Gatling 做深度分析。

想要更多资料,联系可可