压测工具选型:wrk、ab、JMeter、Locust的对比与适用场景

做压测这么多年,我见过太多团队在工具选型上翻车。有人用ab测长连接接口,结果数据惨不忍睹;有人拿JMeter压WebSocket,配置搞了两天还没跑起来。说白了,没有万能工具,只有最合适的场景。

今天我就把这四个主流工具掰开揉碎讲清楚。你想想看,选错工具就像用螺丝刀钉钉子——活能干,但效率低得让人抓狂。

先看一张全景图

下面这张图是我自己整理的选型决策流程。每次接手新项目,我都会先过一遍这个逻辑。

压测工具选型决策图 压测需求分析 接口类型?并发模型?资源限制? wrk C语言 + Lua脚本 ab Apache 自带 JMeter Java GUI Locust Python 协程 高并发HTTP/HTTPS 自定义请求逻辑 简单GET/POST 快速验证 复杂业务流程 分布式压测 动态场景模拟 Web UI监控 选型建议 • 追求极致性能 → wrk(单机10万+连接) • 快速验证接口 → ab(一条命令搞定) • 复杂业务压测 → JMeter(插件生态丰富) • 动态流量模拟 → Locust(Python脚本灵活)

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 原生支持分布式架构

最后说一句——别纠结工具。我见过有人花两周时间对比工具,结果项目延期了。选一个你用得最顺手的,先跑起来再说。数据有了,再换工具也来得及。

想要更多资料,联系可可