压测工具选型:wrk、ab、JMeter、Locust的对比与适用场景
做压测这么多年,我见过太多团队在工具选型上翻车。有人用ab测长连接接口,结果数据惨不忍睹;有人拿JMeter压WebSocket,配置搞了两天还没跑起来。说白了,没有万能工具,只有最合适的场景。
今天我就把这四个主流工具掰开揉碎讲清楚。你想想看,选错工具就像用螺丝刀钉钉子——活能干,但效率低得让人抓狂。
先看一张全景图
下面这张图是我自己整理的选型决策流程。每次接手新项目,我都会先过一遍这个逻辑。
wrk:性能怪兽,但门槛不低
wrk是我个人最常用的工具。为什么?因为它用C语言写的,底层基于epoll/kqueue,单机就能压出10万级别的并发连接。我记得有一次帮客户压一个网关服务,用JMeter跑了半天CPU先满了,换成wrk直接干到12万QPS,机器还稳得很。
核心优势:
- 基于事件驱动,内存占用极低
- 支持Lua脚本自定义请求逻辑
- 输出延迟分布(Latency Distribution)非常详细
但wrk有个硬伤——它只支持HTTP/HTTPS协议。你想压WebSocket?不行。想压gRPC?没门。而且Lua脚本虽然灵活,但调试起来挺痛苦的。我刚开始用的时候,一个签名逻辑的Lua脚本调了整整一下午。
# 一个典型的wrk压测命令
wrk -t12 -c400 -d30s --latency http://target.com/api
# 带Lua脚本的复杂场景
wrk -t4 -c200 -d60s -s custom.lua http://target.com/api
我的经验:wrk最适合压RESTful API和静态资源服务。如果你需要压HTTPS,记得加上--timeout参数,不然SSL握手可能拖垮你的压测机。
ab:老兵不死,只是凋零
ab(Apache Bench)是Apache自带的压测工具。说实话,现在我用它的场景越来越少了。但它有个无可替代的优势——几乎每台Linux服务器都自带,不用装任何依赖。
我曾经在客户现场,网络环境受限,没法装wrk。我直接ssh上去敲了个ab -n 10000 -c 100 http://.../,5分钟就拿到了初步数据。这种场景下,ab就是救命稻草。
注意:ab的并发模型是fork子进程,并发高了CPU消耗巨大。我实测过,超过500并发,ab本身的CPU占用就超过50%了。所以它只适合做快速验证,别拿它做正式的性能基准测试。
| 特性 | ab | wrk |
|---|---|---|
| 并发模型 | 多进程 | 事件驱动 |
| 最大并发 | ~500 | 10万+ |
| 安装难度 | 零安装 | 需编译/包管理 |
| 协议支持 | HTTP/HTTPS | HTTP/HTTPS |
JMeter:重型武器,功能全面
JMeter是个大家伙。它基于Java,有完整的GUI界面,支持录制回放、参数化、断言、监听器……说白了,你能想到的压测功能它都有。
但我要泼盆冷水——JMeter的资源消耗非常夸张。我曾经用JMeter压一个简单的登录接口,8核16G的机器,压到2000并发,JMeter自己先OOM了。后来排查发现,是GUI模式下的监听器在疯狂写日志。
JMeter的正确打开方式:
- 用命令行模式运行:
jmeter -n -t test.jmx -l result.jtl - 关掉不必要的监听器,尤其是View Results Tree
- 分布式压测时,确保Agent和Controller网络延迟小于1ms
JMeter的插件生态确实丰富。我做过一个需要压WebSocket的场景,wrk和ab都搞不定,JMeter装了个WebSocket插件,半小时就配好了。这种时候你不得不服它的生态。
Locust:Python玩家的最爱
Locust用Python写,基于协程(gevent)。它的最大卖点是——你可以用Python写压测脚本。这意味着什么?意味着你可以直接复用项目里的工具函数、数据库连接、加密逻辑。
我记得有一次压一个需要动态签名的接口。用wrk写Lua脚本,签名逻辑搞了2小时没跑通。换成Locust,直接把项目里的sign.py import进来,10分钟搞定。这就是Python生态的力量。
# Locust的压测脚本示例
from locust import HttpUser, task, between
class WebsiteUser(HttpUser):
wait_time = between(1, 5)
@task
def index_page(self):
self.client.get("/")
@task(3)
def view_item(self):
item_id = random.randint(1, 1000)
self.client.get(f"/item?id={item_id}", name="/item")
避坑指南:我曾经用Locust压一个高并发场景,发现协程模式下CPU上下文切换开销不小。如果你要压10万+并发,建议还是用wrk。Locust更适合压几千并发的动态业务场景。
选型总结:一张表说清楚
| 场景 | 推荐工具 | 理由 |
|---|---|---|
| 高并发HTTP压测(10万+) | wrk | 事件驱动,资源占用极低 |
| 快速验证接口可用性 | ab | 零安装,一条命令搞定 |
| 复杂业务流程压测 | JMeter | 插件丰富,支持录制回放 |
| 动态签名/自定义逻辑 | Locust | Python脚本,复用现有代码 |
| WebSocket/gRPC压测 | JMeter + 插件 | 生态最全,社区支持好 |
| 分布式压测 | JMeter / Locust | 原生支持分布式架构 |
最后说一句——别纠结工具。我见过有人花两周时间对比工具,结果项目延期了。选一个你用得最顺手的,先跑起来再说。数据有了,再换工具也来得及。
想要更多资料,联系可可