压测工具选型:JMeter vs Locust vs wrk vs Go-stress-testing

做压测这么多年,我经常被问到同一个问题:到底该用哪个工具?

说实话,没有银弹。每个工具都有自己的脾气。我见过有人用JMeter压一个简单的API,结果自己先被JMeter搞崩溃了。也见过有人用wrk测复杂业务逻辑,测出来的数据根本没法看。

今天我就把这四个主流工具掰开揉碎讲清楚。你根据自己的场景选就行。

核心观点:工具没有绝对的好坏,只有适不适合你的场景。选错工具,压测结果就是废纸。

一、先看一张全景图

压测工具选型全景图 JMeter GUI/协议丰富/重 Locust Python/协程/灵活 wrk C语言/高性能/轻量 Go-stress-testing Go/并发/简单 评估维度 学习成本 性能上限 协议支持 分布式能力 推荐场景 复杂业务压测 多协议/断言/报告 自定义场景 Python脚本/动态逻辑 纯性能测试 高并发/低资源 快速验证 单接口/简单场景

二、逐个拆解

1. JMeter — 压测界的瑞士军刀

JMeter是我最早接触的压测工具。说实话,第一次打开那个GUI界面,我有点懵。功能太多了。

优点:

  • 协议支持最全:HTTP、HTTPS、WebSocket、JDBC、JMS...你能想到的它基本都有
  • GUI界面直观:点点点就能配出复杂场景
  • 插件生态丰富:各种监听器、断言、前置处理器
  • 分布式压测:一台Master控制多台Slave

缺点:

  • 资源消耗大:开个GUI就吃掉几百MB内存
  • 脚本维护麻烦:jmx文件是XML格式,版本对比基本靠眼
  • 高并发场景不稳定:我记得有一次压5000并发,JMeter自己先OOM了

我的建议:如果你需要测复杂业务流程(比如登录→下单→支付),或者需要各种断言和报告,JMeter是首选。但记得用命令行模式跑,别开GUI。

# 命令行模式示例
jmeter -n -t test_plan.jmx -l results.jtl -e -o report/

2. Locust — Python玩家的最爱

Locust是我个人比较喜欢的工具。为什么?因为用Python写压测脚本,太灵活了。

优点:

  • 脚本即代码:用Python定义用户行为,想怎么玩就怎么玩
  • 协程机制:基于gevent,单机并发能力不错
  • Web UI实时监控:跑起来能看到实时QPS、响应时间
  • 分布式原生支持:启动多个worker就行

缺点:

  • 性能上限不如wrk:毕竟是Python,GIL锁摆在那
  • 协议支持有限:主要针对HTTP,其他协议需要自己写
  • 报告功能弱:默认报告比较简陋

避坑指南:我曾经用Locust压一个长连接服务,结果协程池配置不对,压测机先挂了。记住,Locust的并发数不等于实际TCP连接数,这个坑很多人踩过。

# 一个简单的Locust脚本
from locust import HttpUser, task, between

class WebsiteUser(HttpUser):
    wait_time = between(1, 5)
    
    @task
    def index(self):
        self.client.get("/")

3. wrk — 性能怪兽

wrk是我压测纯接口性能时的首选。它用C语言写的,就一个二进制文件,几MB大小。

优点:

  • 性能极高:利用多核CPU和epoll/kqueue,单机轻松压出几十万QPS
  • 资源占用极低:跑10万并发,内存占用不到100MB
  • Lua脚本扩展:可以写Lua脚本定制请求逻辑

缺点:

  • 功能单一:只支持HTTP协议,没有断言、没有报告
  • 学习曲线陡:Lua脚本虽然灵活,但写起来不如Python顺手
  • 不支持分布式:单机工具,没法多机协同

适用场景:你只是想看看某个接口的极限QPS是多少,或者对比不同配置下的性能差异。这时候wrk是最佳选择。

# wrk基本用法
wrk -t12 -c400 -d30s http://target.com/api

# 带Lua脚本的用法
wrk -t4 -c100 -d60s -s script.lua http://target.com/api

4. Go-stress-testing — 国产新秀

这个工具是我最近两年才开始用的。Go语言写的,编译出来就一个二进制,跨平台直接跑。

优点:

  • 部署简单:下载就能用,不需要装任何依赖
  • 并发模型优秀:Go的goroutine,单机并发能力很强
  • 支持多种协议:HTTP、WebSocket、TCP、gRPC
  • 实时输出:跑的时候能看到实时QPS和响应时间

缺点:

  • 社区较小:遇到问题可能找不到现成的解决方案
  • 功能不够丰富:没有JMeter那么多插件
  • 报告生成弱:需要自己二次处理结果

我的经验:做快速验证或者给开发同学演示的时候,我经常用Go-stress-testing。一行命令就能跑起来,效果很直观。

# Go-stress-testing基本用法
./go-stress-testing -c 100 -n 10000 -u http://target.com/api

# 带参数的POST请求
./go-stress-testing -c 50 -n 5000 -u http://target.com/api -d '{"key":"value"}' -H "Content-Type: application/json"

三、横向对比

维度 JMeter Locust wrk Go-stress-testing
学习成本 中高 低(需Python基础) 中(需Lua基础) 低
性能上限 中 中 高 高
协议支持 丰富 有限 仅HTTP 较多
分布式 支持 支持 不支持 不支持
报告能力 强 中 弱 弱
资源占用 高 中 低 低
脚本维护 难(XML) 易(Python) 中(Lua) 易(命令行)

四、我的选型建议

说了这么多,到底怎么选?我总结几条经验:

  1. 复杂业务场景 → JMeter。别犹豫,它的插件和协议支持是其他工具比不了的。
  2. 需要灵活定制 → Locust。特别是你要模拟复杂的用户行为,Python脚本能搞定一切。
  3. 纯性能测试 → wrk。就想看看接口能扛多少并发,wrk是最轻量高效的选择。
  4. 快速验证 → Go-stress-testing。开发同学临时要测个接口,扔给他这个工具最省事。

最后说一句:我见过太多人纠结工具选型,结果花了两周研究工具,真正压测只用了半天。工具是手段,不是目的。先想清楚你要测什么,再选工具。

嗯,工具选型这块就聊到这。记住,没有最好的工具,只有最合适的工具。