4. 压测工具选型
大家好,我是你们的老朋友。今天咱们聊聊压测工具选型这件事。
说实话,我见过太多团队一上来就拍脑袋选工具。结果压测跑一半,工具先崩了。或者测出来的数据,跟线上表现完全对不上。嗯,这其实挺常见的。
我个人习惯是,先搞清楚场景,再挑工具。GPU场景下的压测,跟普通Web压测完全是两码事。你想想看,显存峰值优化,核心是看模型推理时显存怎么涨、怎么降。普通压测工具根本看不到这层。
好,咱们直接进入正题。
主流压测工具:wrk、ab、locust、JMeter
这四个工具,我基本都用过。各有各的脾气。
| 工具 | 语言 | 并发模型 | 协议支持 | 资源开销 | 适用场景 |
|---|---|---|---|---|---|
| wrk | C | 多线程 + epoll | HTTP | 极低 | 纯HTTP吞吐测试 |
| ab | C | 多进程 | HTTP | 低 | 简单GET/POST测试 |
| locust | Python | 协程 (gevent) | HTTP, 可扩展 | 中等 | 复杂业务场景模拟 |
| JMeter | Java | 线程池 | HTTP, JDBC, gRPC等 | 较高 | 全链路压测、接口组合 |
逐个拆解
wrk:轻量级吞吐利器
wrk是我个人最常用的工具之一。它用C写的,底层走epoll,单机就能压出几十万QPS。我在项目中遇到过,用wrk压一个纯静态页面,8核机器轻松跑到40万QPS。机器CPU都没跑满。
但wrk有个硬伤——只支持HTTP。而且它的Lua脚本扩展能力有限,做不了复杂的业务逻辑。说白了,它就是个「纯打流」的工具。
适用场景:GPU推理服务的HTTP接口吞吐摸底。比如你部署了一个BERT模型,想知道裸接口能扛多少并发。用wrk最合适。
# 一个典型的wrk压测命令
wrk -t12 -c400 -d30s http://your-gpu-service:8080/predict
ab:老牌工具,但有点过时
ab是Apache自带的压测工具。说实话,我现在很少用它。为什么?因为它用多进程模型,并发高了以后,进程切换开销很大。我曾经试过用ab压1000并发,结果ab自己先卡死了。
不过ab有个优点:安装简单,几乎每个Linux发行版都自带。临时应急用一下还行。
注意:ab不支持Keep-Alive连接复用。这意味着每次请求都要新建TCP连接。在GPU场景下,这会引入额外的网络延迟,干扰显存峰值的判断。
locust:Python玩家的首选
locust用Python写,基于gevent协程。它的最大优势是——你可以用Python写压测脚本。这意味着什么?你可以直接在脚本里调用GPU监控API,实时采集显存数据。
我在项目中做过一个骚操作:用locust压GPU服务,同时在脚本里用nvidia-ml-py库采集显存占用。压测跑完,显存变化曲线直接画出来了。这活wrk和ab干不了。
小技巧:locust的每个用户(User)可以自定义行为。你可以在on_start里初始化GPU上下文,在on_stop里释放。这样能模拟真实用户的显存生命周期。
# locust脚本示例:压测时采集显存
from locust import HttpUser, task, between
import pynvml
class GPUUser(HttpUser):
wait_time = between(1, 3)
def on_start(self):
pynvml.nvmlInit()
self.handle = pynvml.nvmlDeviceGetHandleByIndex(0)
@task
def predict(self):
# 压测前记录显存
mem_before = pynvml.nvmlDeviceGetMemoryInfo(self.handle).used
self.client.post("/predict", json={"text": "hello"})
# 压测后记录显存
mem_after = pynvml.nvmlDeviceGetMemoryInfo(self.handle).used
print(f"显存变化: {mem_before} -> {mem_after}")
JMeter:重型武器
JMeter功能最全,但也是最重的。它支持HTTP、JDBC、gRPC,甚至能压消息队列。我见过有人用JMeter做全链路压测,从网关到数据库全压一遍。
但JMeter在GPU场景下有个致命问题——它本身是Java写的,启动就要占几百MB内存。如果你在压测机器上同时跑JMeter和GPU监控,内存可能先爆了。我曾经在16GB的机器上跑JMeter压测,结果JMeter自己吃了4GB,GPU显存监控反而没空间了。
我的建议:除非你需要压测复杂的业务流程(比如先登录、再查询、再推理),否则别用JMeter。杀鸡不用牛刀。
GPU场景下的压测工具选择
好,重点来了。GPU场景下,压测工具选型要考虑三个维度:
- 能否感知显存——工具本身或扩展能否采集GPU指标
- 并发模型是否匹配——GPU推理是计算密集型,不是IO密集型
- 资源开销是否可控——压测工具不能跟模型抢显存
我画了一张图,帮你理清思路:
我的最终推荐
说了这么多,直接给结论吧:
- 显存峰值摸底:用wrk + 外部监控脚本(nvidia-smi)。wrk负责打流,监控脚本负责采集。两者分离,互不干扰。
- 复杂业务压测:用locust。直接在脚本里集成GPU监控,实时看显存变化。我习惯在locust的请求前后打点,记录每次推理的显存增量。
- 全链路压测:用JMeter。但注意给JMeter分配独立机器,别跟GPU服务混部。
避坑指南:我曾经在压测时犯过一个低级错误——用ab压GPU服务,结果ab的短连接导致GPU服务频繁创建销毁推理上下文。显存像过山车一样忽高忽低,根本看不出真实峰值。后来换成wrk用长连接,数据才稳定下来。
嗯,工具选型就聊到这儿。记住一句话:没有最好的工具,只有最合适的工具。你的场景决定了你的选择。
个人习惯:我一般会准备两套压测方案。一套用wrk做快速摸底,10分钟出结果。另一套用locust做精细化压测,跑30分钟以上,采集完整的显存变化曲线。两套数据对比着看,心里才有底。