4. 压测工具选型:主流压测工具对比与实战配置
说到压测工具选型,我见过不少团队在这个问题上纠结很久。有的盲目追求高性能工具,结果脚本写起来痛苦不堪;有的选了最易上手的,压到一半发现并发上不去。说白了,没有最好的工具,只有最适合你场景的。
这一章,我就结合自己这些年踩过的坑,把主流工具掰开揉碎了讲清楚。你想想看,选错工具的代价是什么?可能是整个压测周期延长一倍,甚至得出错误的性能结论。
4.1 主流压测工具横向对比
先看一张我整理的对比表,这样你心里有个大概的谱:
| 工具 | 语言 | 协议支持 | 并发模型 | 脚本复杂度 | 分布式支持 | 学习曲线 |
|---|---|---|---|---|---|---|
| JMeter | Java | HTTP/HTTPS/WebSocket/JDBC/自定义 | 线程池 | 低(GUI拖拽) | 原生支持 | 低 |
| Locust | Python | HTTP/HTTPS/自定义 | 协程(gevent) | 中(Python代码) | 原生支持 | 中 |
| Gatling | Scala | HTTP/HTTPS/WebSocket/JMS | Akka Actor | 高(DSL脚本) | 原生支持 | 高 |
| wrk | C/Lua | HTTP/HTTPS | 事件驱动(epoll) | 低(命令行+Lua) | 需第三方 | 低 |
4.2 逐个拆解:我的实战感受
JMeter — 老牌劲旅,但别被GUI骗了
JMeter是我最早接触的压测工具。说实话,它的GUI界面确实友好,拖拖拽拽就能生成脚本。但我在项目中遇到过一个大坑:GUI模式下的压测结果不准。为什么呢?因为GUI本身会消耗系统资源,尤其是线程数上去后,JMeter自己先成了瓶颈。
JMeter的优势在于协议支持广泛。除了HTTP,它还支持JDBC、JMS、WebSocket等。如果你需要压测数据库或者消息队列,JMeter几乎是唯一的选择。
安装很简单,去官网下载二进制包,解压就能用:
# 下载JMeter
wget https://dlcdn.apache.org//jmeter/binaries/apache-jmeter-5.6.3.tgz
tar -xzf apache-jmeter-5.6.3.tgz
cd apache-jmeter-5.6.3/bin
# 启动GUI(调试用)
./jmeter
# 启动命令行(压测用)
./jmeter -n -t test_plan.jmx -l results.jtl -e -o report_dir
Locust — Python党的最爱
我个人习惯用Locust做快速验证。它的核心思想是用Python代码描述用户行为,非常灵活。你想想看,如果被测接口需要先登录获取token,再携带token访问业务接口,用JMeter的BeanShell脚本写起来多痛苦?Locust几行代码就搞定了。
from locust import HttpUser, task, between
class WebsiteUser(HttpUser):
wait_time = between(1, 5) # 模拟用户思考时间
def on_start(self):
# 登录获取token
resp = self.client.post("/login", json={"user": "test", "pass": "123"})
self.token = resp.json()["token"]
@task(3)
def view_home(self):
self.client.get("/home", headers={"Authorization": f"Bearer {self.token}"})
@task(1)
def view_profile(self):
self.client.get("/profile", headers={"Authorization": f"Bearer {self.token}"})
Locust的并发模型基于协程(gevent),这意味着单机就能轻松模拟数千并发。我在项目中用一台4核8G的云服务器跑Locust,压到5000并发都没问题。换成JMeter,同样配置可能到2000就开始报OOM了。
Gatling — 高性能但门槛高
Gatling是我见过性能最猛的压测工具之一。它基于Akka Actor模型,天生就是为高并发设计的。我记得有一次压测一个直播平台的弹幕接口,JMeter跑到3000并发就开始丢数据,换成Gatling轻松跑到8000并发,而且结果曲线非常平滑。
但Gatling的脚本是用Scala DSL写的,学习曲线确实陡。你看这个脚本:
import io.gatling.core.Predef._
import io.gatling.http.Predef._
class BasicSimulation extends Simulation {
val httpProtocol = http
.baseUrl("https://api.example.com")
.acceptHeader("application/json")
val scn = scenario("Basic Scenario")
.exec(http("request_1")
.get("/users")
.check(status.is(200)))
setUp(
scn.inject(atOnceUsers(100))
).protocols(httpProtocol)
}
说实话,如果不是团队里有Scala基础的人,我不建议轻易上Gatling。但如果你需要压测WebSocket或者JMS协议,Gatling的DSL表达能力确实比JMeter强很多。
wrk — 轻量级利器,适合快速压测
wrk是我最常用的快速压测工具。它基于epoll事件驱动模型,单机就能压出很高的并发。安装也简单:
# 安装依赖
sudo apt-get install build-essential libssl-dev
# 编译安装
git clone https://github.com/wg/wrk.git
cd wrk
make
sudo cp wrk /usr/local/bin/
# 快速压测
wrk -t12 -c400 -d30s https://api.example.com/users
这个命令的意思是:用12个线程,保持400个并发连接,持续压30秒。输出结果非常简洁:
Running 30s test @ https://api.example.com/users
12 threads and 400 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 45.67ms 12.34ms 189.00ms 75.00%
Req/Sec 734.56 89.23 1.02k 70.00%
263456 requests in 30.00s, 1.02GB read
Requests/sec: 8781.87
Transfer/sec: 34.78MB
wrk的缺点也很明显:只支持HTTP/HTTPS协议,而且脚本能力弱。虽然可以用Lua脚本做一些简单的请求定制,但复杂场景基本没戏。我一般用它来做接口的基准测试,快速判断一个接口的性能基线。
4.3 工具选型考量因素
说了这么多,到底怎么选?我总结了一个决策框架:
- 协议类型:如果只压HTTP,wrk或Locust就够了。如果需要JDBC、JMS等,只能选JMeter或Gatling。
- 并发规模:单机5000并发以内,Locust性价比最高。超过5000,考虑Gatling或分布式JMeter。
- 团队技术栈:Java团队选JMeter,Python团队选Locust,Scala团队选Gatling。别为了工具换语言,成本太高。
- 报告需求:JMeter和Gatling自带HTML报告,Locust需要配合InfluxDB+Grafana。如果客户要求漂亮的报告,Gatling的图表最专业。
- 持续集成:JMeter有Maven/Gradle插件,Gatling有sbt插件,Locust可以直接用Python的unittest框架。选跟你们CI/CD流水线集成最方便的。
我的建议:团队至少掌握两个工具。一个轻量级的(wrk或Locust)做快速验证,一个重量级的(JMeter或Gatling)做全链路压测。我自己是「Locust + JMeter」组合,覆盖了90%的场景。
4.4 工具安装与基础配置
这里我给出最常用的安装方式,避免你走弯路。
JMeter 安装配置
# 1. 安装JDK(JMeter需要Java 8+)
sudo apt-get install openjdk-11-jdk
# 2. 下载JMeter
wget https://dlcdn.apache.org//jmeter/binaries/apache-jmeter-5.6.3.tgz
tar -xzf apache-jmeter-5.6.3.tgz -C /opt/
# 3. 配置环境变量
echo 'export JMETER_HOME=/opt/apache-jmeter-5.6.3' >> ~/.bashrc
echo 'export PATH=$JMETER_HOME/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
# 4. 验证安装
jmeter --version
HEAP="-Xms4g -Xmx8g -XX:MaxMetaspaceSize=512m"
Locust 安装配置
# 使用pip安装
pip install locust
# 验证安装
locust --version
# 启动(Web UI模式)
locust -f locustfile.py --host=https://api.example.com
# 启动(无头模式,适合CI/CD)
locust -f locustfile.py --host=https://api.example.com --headless -u 1000 -r 100 --run-time 5m
Gatling 安装配置
# 下载Gatling
wget https://repo1.maven.org/maven2/io/gatling/highcharts/gatling-charts-highcharts-bundle/3.11.5/gatling-charts-highcharts-bundle-3.11.5.zip
unzip gatling-charts-highcharts-bundle-3.11.5.zip -d /opt/
# 进入目录
cd /opt/gatling-charts-highcharts-bundle-3.11.5
# 运行示例压测
./bin/gatling.sh
# 运行自定义压测
./bin/gatling.sh -s com.example.BasicSimulation
wrk 安装配置
# 编译安装(前面已讲)
# 常用参数说明
wrk -t<线程数> -c<连接数> -d<持续时间> <URL>
# 使用Lua脚本定制请求
wrk -t4 -c200 -d30s -s post.lua https://api.example.com/login
嗯,到这里四种工具的安装和基础配置就讲完了。你可能会问:「我到底该先学哪个?」我的建议是:先学Locust,因为它上手快、Python生态好、单机性能强。等你把压测流程跑通了,再根据实际需求去学JMeter或Gatling。
最后送你一句话:工具只是手段,理解系统瓶颈才是目的。别在工具选型上浪费太多时间,先跑起来再说。
公众号:蓝海资料掘金营,微信deep3321