压测工具选择:wrk、ab、JMeter、Locust、Vegeta 对比归纳

说实话,市面上的压测工具多到让人眼花。刚开始接触 SDK 性能测试那会儿,我也是挨个试错。你想想看,选错工具不仅浪费时间,测出来的数据可能根本没用。

我个人习惯把工具按“场景”分类。不是比谁功能多,而是看谁在特定任务里最顺手。下面这五款是我实战中打磨出来的主力阵容。

工具速览与核心定位

工具 语言/运行方式 并发模型 典型场景
wrk C / 命令行 多线程 + epoll/kqueue 纯 HTTP 接口吞吐量摸底
ab (Apache Bench) C / 命令行 多进程 快速验证、简单 GET 请求
JMeter Java / GUI + CLI 线程池 + 采样器 复杂业务流、多协议、断言链
Locust Python / 脚本 + Web UI 协程 (gevent) 模拟真实用户行为、微秒级控制
Vegeta Go / 命令行 + 库 goroutine + 速率控制 精确限速、持续压测、报告生成

我的核心原则:压测工具不是越重越好。对于 SDK 压测,我优先用轻量级工具做基线摸底,再用重工具做场景覆盖。

逐工具深度剖析

wrk — 我压测路上的“瑞士军刀”

wrk 是我用得最多的工具。它用 C 语言编写,基于 epoll(Linux)或 kqueue(macOS)实现高性能事件循环。说白了,它能用很少的线程撑起很高的并发。

我记得有一次压测一个 SDK 的 HTTP 上报接口。机器是 4 核 8G,用 wrk 只开了 4 个线程,就把目标机器打到了 3 万 QPS。同样的场景,用 ab 跑 CPU 直接吃满,结果还偏低。

小技巧:wrk 支持 Lua 脚本扩展。我经常用它做简单的 body 拼接或 刷新。虽然不如 JMeter 灵活,但胜在速度极快。

# 基础用法:100 个连接,4 个线程,持续 30 秒
wrk -t4 -c100 -d30s http://target:8080/api/report

# 带 Lua 脚本的自定义压测
wrk -t4 -c100 -d30s -s custom.lua http://target:8080/api/report

ab — 简单到粗暴

ab 是 Apache 自带的压测工具。它简单到什么程度?一条命令就能跑起来。但别被它的简单骗了,ab 有几个坑我一直记着。

首先,ab 是单进程多线程的。在高并发下,它自身会成为瓶颈。我曾经用 ab 压测一个本地服务,目标 QPS 还没到 5000,ab 自己的 CPU 已经 100% 了。

避坑:ab 不支持 POST body 长度动态变化,也不支持 Cookie 管理。用它压测真实场景的 SDK 接口,数据往往偏乐观。我一般只用来做“服务是否存活”的快速验证。

# 快速验证:100 个请求,10 个并发
ab -n 100 -c 10 http://target:8080/health

JMeter — 重武器,适合复杂场景

JMeter 是 Java 生态里的庞然大物。它支持 HTTP、JDBC、MQ 等各种协议,还能做断言、关联、参数化。对于 SDK 压测,它最大的价值在于录制和回放。

我在项目中遇到过需要压测一个 SDK 的多步登录流程。第一步获取 ,第二步携带 请求业务接口,第三步刷新 。用 JMeter 的「正则表达式提取器」和「后置处理器」可以串联起来。

注意点:JMeter 的 GUI 模式会消耗不少资源。真正跑压测时,一定要用 CLI 模式,并加上 -n 参数。否则你压测的结果会包含 GUI 的开销。

#  CLI 模式运行压测
jmeter -n -t test_plan.jmx -l result.jtl -e -o report/

Locust — 用 Python 写压测脚本

Locust 的卖点是“像写单元测试一样写压测”。它用 Python 的协程(gevent)模拟用户行为。每个用户是一个协程,可以自由控制 wait_time 和任务权重。

我喜欢用它来模拟 SDK 的真实业务行为。你想想看,SDK 的用户不是每秒钟都在发请求的。他们会有思考时间、操作间隙。Locust 的 between(1, 5) 可以模拟用户平均等待 1~5 秒。

个人经验:Locust 的 Web UI 很直观,可以在压测过程中动态调整用户数。这个功能在调试阶段特别有用。我发现某个接口有性能问题时,直接加用户数复现,不用改脚本。

# 简单的 Locust 用户脚本
from locust import HttpUser, task, between

class SDKUser(HttpUser):
    wait_time = between(1, 5)

    @task
    def report_data(self):
        self.client.post("/api/report", json={"sdk_version": "4.2.1"})

Vegeta — 极速压测,精准限速

Vegeta 是 Go 语言写的。它最强大的能力是“速率控制”。你可以精确设定每秒发多少个请求,而不是像 wrk 那样“尽力而为”。

这对于测试 SDK 的“限流”逻辑非常有用。我曾经需要验证一个 SDK 在 100 QPS 下是否稳定。用 Vegeta 设置速率,压了整整一个小时,数据非常稳定。

# 以 100 QPS 的速率压测,持续 60 秒
echo "GET http://target:8080/api/report" | vegeta attack -rate=100 -duration=60s | vegeta report

# 输出为二进制报告,方便后续分析
echo "GET http://target:8080/api/report" | vegeta attack -rate=100 -duration=60s > results.bin

为什么推荐这个?SDK 的性能测试通常需要看“在固定压力下的响应时间分布”,而不是“最大能抗多少 QPS”。Vegeta 的速率精确控制,让我能快速复现线上流量。

工具选择逻辑与决策流程图

光了解工具特性还不够。你得学会在项目开始时,快速判断用哪一把刀。下面这张图是我自己的决策逻辑。

压测工具选择决策流程 开始压测选型 确定流量特征:协议&并发量 纯 HTTP,高并发 多协议,复杂业务流 需要精确限速? 是 → Vegeta 否 → wrk/ab 需要脚本控制行为? 是 → Locust 否 → JMeter 执行压测 → 收集指标 → 迭代调优 提示:新手建议从 wrk 或 Vegeta 入手 等遇到业务场景复杂时再换 Locust 或 JMeter

最终选择建议与避坑

我把这些年踩过的坑总结了一下。每个坑都对应一个真实案例。

  • 不要混用工具的并发模型:wrk 的“并发”是连接数。JMeter 的“并发”是线程数。Locust 的“并发”是用户数。三者不能直接画等号。
  • 机器资源要留余量:压测机本身别成为瓶颈。我曾经用一台 2 核的笔记本去压测高性能 SDK,结果压测机先崩了。
  • 看分布,别看平均:Latency 的 P99 比平均值更有价值。Vegeta 和 wrk 都支持输出百分位延迟分布。
  • 预热很关键:很多 SDK 有懒加载或缓存机制。我习惯先跑 10 秒预热,再记录正式的压测数据。

特别提醒:ab 的并发数是“一次性”的。它会把 -c 参数指定的连接数全部建好再发请求。这在长连接场景下会高估服务器的吞吐量。我踩过这个坑,数据报告交给老板后被要求重新压测。

小结一下

选择压测工具,我建议你从最熟悉的开始。用熟了再横向扩张。我个人经历是从 ab 入门的,被坑了几次后转向 wrk,后来遇到复杂业务流才加入 JMeter 和 Locust。Vegeta 是我做精确限压时的首选。

你想想看,工具只是手段。真正的功夫在于理解 SDK 的业务逻辑,设计出能暴露性能瓶颈的压测场景。不要盲目追求工具的功能多少,关键看它能不能帮你发现问题。