3、压测工具选型:Locust vs JMeter vs wrk,选型对比与实战场景分析
做吞吐压测这么多年,我经常被问到同一个问题:到底该用哪个工具?
说实话,没有银弹。每个工具都有自己的脾气。我见过有人用JMeter压WebSocket,结果把自己搞崩溃了。也见过有人用wrk测复杂业务逻辑,最后发现根本模拟不了真实场景。
今天我就把这三个主流工具掰开揉碎,讲讲它们的核心差异。你听完就知道,什么场景该选谁。
核心结论先放这:
- 追求极致性能,场景简单 → wrk
- 需要复杂业务模拟,团队有Java基础 → JMeter
- 想要灵活编程,快速迭代 → Locust
3.1 三款工具的底层逻辑差异
先看一张图,帮你快速建立整体认知。
3.2 wrk:轻量级性能之王
wrk 是我个人做接口基准测试的首选。它基于 C 语言开发,底层用了 epoll 和 kqueue,单机就能压出几十万的 QPS。
它的核心优势就一个字:快。
举个例子,我想看看 Nginx 的极限吞吐。用 wrk 写个 Lua 脚本,几行代码搞定:
-- wrk 自定义 Lua 脚本示例
wrk.method = "POST"
wrk.body = '{"user_id": 12345}'
wrk.headers["Content-Type"] = "application/json"
response = function(status, headers, body)
if status ~= 200 then
print("请求失败: " .. status)
end
end
启动命令也简单:
wrk -t12 -c400 -d30s --latency http://localhost:8080/api
这里 -t12 表示 12 个线程,-c400 是 400 个并发连接,-d30s 持续 30 秒。跑完直接出结果,包括延迟分布。
我的经验:wrk 适合做单接口的极限压测。比如你想知道网关能扛多少并发,或者数据库连接池的瓶颈在哪。但别用它做复杂的业务流程,它不支持 cookie 管理、session 保持这些高级功能。
注意:wrk 在 Windows 上支持不太好。我建议你在 Linux 或 macOS 上用。如果你团队全是 Windows 环境,那 wrk 可能不是最佳选择。
3.3 JMeter:企业级压测的瑞士军刀
JMeter 是我在复杂业务场景下的首选。它最大的优势是生态丰富,几乎你能想到的协议它都支持:HTTP、HTTPS、WebSocket、JDBC、JMS、FTP……
我记得有一次,需要压测一个包含登录、下单、支付三个步骤的电商流程。用 JMeter 的逻辑控制器和正则提取器,半小时就搭好了:
<!-- JMeter 测试计划结构示例 -->
测试计划
├── 线程组 (100用户, 循环10次)
│ ├── HTTP请求 - 登录
│ │ └── 正则提取器 (提取token)
│ ├── HTTP请求 - 下单
│ │ └── JSON提取器 (提取orderId)
│ ├── HTTP请求 - 支付
│ │ └── 响应断言 (检查状态码)
│ └── 聚合报告
└── 查看结果树
JMeter 的分布式压测能力也很强。一台 Master 控制多台 Slave,轻松扩展到上千并发。
| 特性 | JMeter | 我的评价 |
|---|---|---|
| 协议支持 | 20+ 种协议 | 业界最全 |
| 学习曲线 | 中等 | GUI 操作直观,但深入需要时间 |
| 资源消耗 | 较高 | Java 虚拟机开销大 |
| 报告生成 | 内置 + 插件 | 图表丰富,可定制 |
避坑指南:我曾经用 JMeter 压一个高并发接口,结果发现 Master 节点自己先挂了。后来才意识到,JMeter 的分布式模式下,Master 会收集所有 Slave 的数据,如果数据量太大,Master 的内存会爆。解决方案是:用 InfluxDB + Grafana 做实时监控,别让 Master 存数据。
3.4 Locust:Python 工程师的压测利器
Locust 是我最近两年用得越来越多的工具。原因很简单:用 Python 写压测脚本,太灵活了。
你想想看,如果你的压测场景需要调用外部 API、读取数据库、或者做复杂的条件判断,用 JMeter 的 GUI 配置会非常痛苦。但用 Locust,直接写 Python 代码就行:
from locust import HttpUser, task, between
class WebsiteUser(HttpUser):
wait_time = between(1, 5) # 模拟用户思考时间
@task(3) # 权重3,表示这个任务执行概率更高
def view_homepage(self):
self.client.get("/")
@task(1)
def login_and_order(self):
# 模拟登录
resp = self.client.post("/login", json={
"username": "test_user",
"password": "123456"
})
token = resp.json().get("token")
# 模拟下单
self.client.post("/order", json={
"product_id": 1001,
"quantity": 1
}, headers={"Authorization": f"Bearer {token}"})
Locust 的分布式架构也很优雅。一个 Master 进程负责协调,多个 Worker 进程负责施压。每个 Worker 都是独立的 Python 进程,互不干扰。
我的建议:如果你的团队以 Python 为主,或者压测场景需要频繁调整逻辑,选 Locust 准没错。它还有一个很酷的特性——Web UI 实时监控,可以在浏览器里看到每秒请求数、响应时间、失败率等指标,还能动态调整并发数。
3.5 实战场景选型对照表
说了这么多,我直接给你一个场景对照表。遇到具体需求时,对着查就行:
| 场景 | 推荐工具 | 理由 |
|---|---|---|
| 单接口极限压测 | wrk | 性能极致,资源消耗低 |
| 多步骤业务流程 | JMeter | 逻辑控制器完善,参数提取方便 |
| 自定义协议压测 | Locust | Python 灵活,可扩展性强 |
| WebSocket 压测 | JMeter / Locust | 两者都支持,看团队技术栈 |
| 持续集成流水线 | Locust | 命令行模式,易于集成 |
| 海量数据压测 | JMeter | CSV 数据驱动,参数化方便 |
3.6 我的最终建议
说了这么多,其实我想表达的核心观点就一个:不要迷信工具,要理解场景。
我见过有人用 wrk 压测一个需要登录的接口,结果压了半天全是 401。也见过有人用 JMeter 压一个简单的健康检查接口,结果配置了 50 个监听器,把自己机器搞崩了。
我的做法是:
- 快速验证用 wrk,10 秒出结果
- 复杂业务用 JMeter,GUI 配置直观
- 灵活定制用 Locust,Python 代码随心所欲
三个工具各有千秋。你不需要成为每个工具的专家,但至少要清楚它们的能力边界。这样在遇到具体问题时,才能快速选出最合适的工具。
嗯,工具选型就聊到这。记住,工具是死的,场景是活的。多动手,多踩坑,慢慢你就有感觉了。