第4章:压测工具选型与部署
做交易网关压测这么多年,我经常被问到:「到底该用哪个压测工具?」
说实话,没有银弹。每个工具都有自己的脾气。今天我就把几个主流工具掰开揉碎了讲讲,顺便聊聊我踩过的坑。
4.1 主流压测工具横向对比
先看一张对比表,心里有个底:
| 工具 | 协议支持 | 并发模型 | 脚本语言 | 学习成本 | 适合场景 |
|---|---|---|---|---|---|
| wrk | HTTP/HTTPS | 多线程 + epoll | Lua | 低 | 快速压测、基准测试 |
| JMeter | HTTP、TCP、JDBC等 | 多线程 | GUI配置 + BeanShell | 中 | 复杂业务场景、分布式压测 |
| Locust | HTTP、自定义 | 协程(gevent) | Python | 中 | 灵活定制、持续集成 |
| 自研工具 | 任意 | 自定义 | Go/Java/C++ | 高 | 特定协议、极致性能 |
4.2 逐个聊聊
wrk:轻量级利器
我个人最常用 wrk。为什么?因为它够快、够简单。
wrk 底层用的是 epoll(Linux 下)或 kqueue(macOS 下),加上多线程模型。说白了,它把操作系统的高性能 I/O 复用机制用到了极致。你想想看,一个单机工具能轻松压出几十万 QPS,这还不够香吗?
不过 wrk 也有短板——它只支持 HTTP/HTTPS。如果你要压 TCP 自定义协议,那它帮不上忙。
适用场景:快速验证网关的 HTTP 接口性能、做基准测试、对比不同配置下的吞吐量。
JMeter:老牌全能选手
JMeter 我接触得最早。记得刚入行那会儿,公司压测全用 JMeter。它的插件生态确实丰富,JDBC、JMS、FTP 都能压。
但说实话,JMeter 的并发模型有点「重」。每个虚拟用户就是一个线程,压到几千并发时,JMeter 自己先扛不住了。我曾经在压测一个金融网关时,JMeter 客户端 CPU 跑满,但目标服务器才用了 30% 的资源。嗯,这就是典型的「压测工具成了瓶颈」。
避坑指南:我曾经用 JMeter 压 5000 并发,结果 JMeter 自己 OOM 了。后来改用 wrk,同样的机器轻松压到 2 万并发。所以,高并发场景慎用 JMeter。
Locust:Python 党的最爱
Locust 用协程(gevent)来处理并发,比 JMeter 的线程模型轻量得多。如果你团队里 Python 熟手多,Locust 是个好选择。
我个人觉得 Locust 最大的优势是「可编程性」。你可以用 Python 写出非常复杂的用户行为——比如先登录、再查询、再下单,每一步之间还有随机等待。这在模拟真实用户场景时特别有用。
但 Locust 的 Web UI 在压测过程中会消耗不少资源。我建议压测时关掉 UI,用命令行模式跑。
自研工具:终极方案
当上面这些工具都满足不了你时,就该考虑自研了。
我在上一家公司就自研过一个压测工具。原因很简单——我们的网关用的是自定义的二进制协议,wrk 不支持,JMeter 要写插件太麻烦,Locust 的性能又不够极致。
自研工具的好处是:
- 完全掌控协议细节
- 可以针对硬件做极致优化(比如 CPU 亲和性、大页内存)
- 能精确控制发包时序
但代价也很大:开发周期长、维护成本高。说白了,不是万不得已,别轻易走这条路。
4.3 我的选型建议
根据不同的场景,我一般这样选:
- 快速验证:wrk,5 分钟搞定
- 复杂业务流程:JMeter,GUI 配置方便
- 持续集成 + 灵活定制:Locust,Python 脚本好维护
- 自定义协议 / 极致性能:自研工具
小技巧:我经常先用 wrk 做一轮快速压测,找到大概的性能瓶颈。然后再用 JMeter 或 Locust 做详细的场景压测。这样效率最高。
4.4 wrk 的安装与基本使用
好了,工具选型聊完了。接下来咱们动手装 wrk。
安装 wrk
Linux 上安装最简单:
# Ubuntu / Debian
sudo apt-get install wrk
# CentOS / RHEL(需要先装 EPEL)
sudo yum install epel-release
sudo yum install wrk
# macOS
brew install wrk
如果你喜欢从源码编译,也可以:
git clone https://github.com/wg/wrk.git
cd wrk
make
sudo cp wrk /usr/local/bin/
编译时注意:wrk 依赖 OpenSSL 和 LuaJIT。如果报错,先装这两个库。
基本使用
装好后,跑一个最简单的压测:
wrk -t12 -c400 -d30s http://localhost:8080/api/ping
这条命令的意思是:
-t12:用 12 个线程-c400:保持 400 个并发连接-d30s:压测持续 30 秒
输出结果长这样:
Running 30s test @ http://localhost:8080/api/ping
12 threads and 400 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 12.34ms 8.56ms 123.45ms 75.23%
Req/Sec 3.45k 456.78 5.67k 68.90%
1234567 requests in 30.00s, 1.23GB read
Socket errors: connect 0, read 0, write 0, timeout 0
Requests/sec: 41152.33
Transfer/sec: 41.99MB
几个关键指标:
- Latency:延迟分布,看 Avg 和 Max 就能判断响应速度
- Req/Sec:每个线程每秒处理的请求数
- Requests/sec:总 QPS,这是最核心的指标
- Socket errors:如果有非零值,说明网络或服务端有问题
注意:我第一次用 wrk 时,看到 Socket errors 里有 timeout,以为是服务端扛不住了。后来发现是 wrk 的线程数开太多,超过了 CPU 核心数。把 -t 改成 CPU 核数后,问题就解决了。
常用参数速查
| 参数 | 说明 | 示例 |
|---|---|---|
| -t | 线程数 | -t12 |
| -c | 并发连接数 | -c400 |
| -d | 压测时长 | -d30s |
| -s | 加载 Lua 脚本 | -s script.lua |
| -H | 自定义请求头 | -H "Authorization: Bearer xxx" |
| --latency | 输出延迟分布详情 | --latency |
| --timeout | 超时时间(默认无限) | --timeout 5s |
4.5 本章知识体系
下面这张图帮你理清思路:
这张图的核心逻辑很简单:先明确你的压测场景,再选工具。别一上来就搞自研,也别拿 wrk 去压自定义协议——工具用对了,事半功倍。
好了,这一章就到这里。工具选好了,下一章咱们就开始动手压测了。记住:工具只是手段,理解背后的原理才是关键。