压测工具选择: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 的速率精确控制,让我能快速复现线上流量。
工具选择逻辑与决策流程图
光了解工具特性还不够。你得学会在项目开始时,快速判断用哪一把刀。下面这张图是我自己的决策逻辑。
最终选择建议与避坑
我把这些年踩过的坑总结了一下。每个坑都对应一个真实案例。
- 不要混用工具的并发模型:wrk 的“并发”是连接数。JMeter 的“并发”是线程数。Locust 的“并发”是用户数。三者不能直接画等号。
- 机器资源要留余量:压测机本身别成为瓶颈。我曾经用一台 2 核的笔记本去压测高性能 SDK,结果压测机先崩了。
- 看分布,别看平均:Latency 的 P99 比平均值更有价值。Vegeta 和 wrk 都支持输出百分位延迟分布。
- 预热很关键:很多 SDK 有懒加载或缓存机制。我习惯先跑 10 秒预热,再记录正式的压测数据。
特别提醒:ab 的并发数是“一次性”的。它会把 -c 参数指定的连接数全部建好再发请求。这在长连接场景下会高估服务器的吞吐量。我踩过这个坑,数据报告交给老板后被要求重新压测。
小结一下
选择压测工具,我建议你从最熟悉的开始。用熟了再横向扩张。我个人经历是从 ab 入门的,被坑了几次后转向 wrk,后来遇到复杂业务流才加入 JMeter 和 Locust。Vegeta 是我做精确限压时的首选。
你想想看,工具只是手段。真正的功夫在于理解 SDK 的业务逻辑,设计出能暴露性能瓶颈的压测场景。不要盲目追求工具的功能多少,关键看它能不能帮你发现问题。