ab(ApacheBench)压测实战
更新时间:2026-09-19。ab 是 Apache 自带的轻量压测工具,优点是随处可用、零学习成本,适合对单个 URL 做 5 分钟快速摸底。高并发或复杂请求请用 wrk,gRPC 用 ghz。
一、最常用命令
bash
# 总请求 10000、并发 100
ab -n 10000 -c 100 http://127.0.0.1:8080/api/ping
# 长连接(keep-alive),更接近连接复用的线上场景
ab -n 100000 -c 200 -k http://127.0.0.1:8080/
# POST JSON(-p 指定 body 文件,-T 指定 Content-Type)
ab -n 5000 -c 50 -p body.json -T application/json http://127.0.0.1:8080/api/login
# 带超时(秒)与认证头
ab -n 1000 -c 50 -s 10 -H 'Authorization: Bearer xxx' http://127.0.0.1:8080/me| 参数 | 含义 |
|---|---|
-n | 总请求数(务必远大于 -c,否则统计无意义) |
-c | 并发数(同时在飞的请求) |
-k | 启用 HTTP keep-alive 长连接 |
-p/-T | POST body 文件 / Content-Type |
-H | 自定义请求头,可多个 |
-s | 单个请求超时(秒) |
-t | 限时压测(秒),与 -n 二选一 |
二、结果怎么读
bash
Complete requests: 10000
Failed requests: 12 # 非 2xx/连接失败,重点看
Requests per second: 8432.15 [#/sec] (mean) # QPS(吞吐)
Time per request: 11.86 [ms] (mean) # 口径A:并发批耗时/c
Time per request: 0.119 [ms] (mean, across all concurrent requests) # 口径B:单请求视角- Requests per second:核心吞吐指标,但要结合 Failed requests 一起看(高 QPS + 大量失败没有意义)。
- 两个 Time per request 别混淆:第一个是「一批
-c个并发请求的平均耗时」,第二个是「总时间摊到每个请求」≈ 1/QPS;判断单用户延迟看前者,评估吞吐看后者。 - ab 默认不输出分位数,只有最快/最慢/50%/90% 等少量行;要 P95/P99 用 wrk 的
--latency,分位含义见 P99 延迟。
三、正确的压测姿势
- 逐步加压:
-c从 10→50→100→2000 阶梯跑,找到 QPS 不再线性增长、延迟开始陡增的拐点,而不是一上来满并发。 - 先预热再测:先跑一小波让 JIT/连接池/缓存预热,再取稳定段结果。
- 盯被测端:同时看 CPU、GC(jstat)、连接数、错误日志,判断瓶颈在服务还是压测机。
- 区分长短连接:
-k与不用-k结果差异巨大,按线上真实情况选。 - 压测机别成为瓶颈:ab 偏阻塞模型,高并发时压测机单核可能先打满,此时数字反映的是客户端上限。
四、ab 与 wrk 怎么选
| 维度 | ab | wrk |
|---|---|---|
| 上手 | 极简 | 稍多 |
| 模型 | 阻塞式,单机并发有限 | epoll 事件驱动多线程 |
| 动态请求 | 基本不支持 | Lua 脚本 |
| 延迟分位 | 仅少量 | --latency 给 P50/P90/P99 |
| 适用 | 单 URL 快速摸底 | 正式压测、找拐点 |
坑
-n设得比-c还小,统计样本不足,结果不可信。- 只盯 QPS 不看 Failed requests 和非 2xx,得到「高吞吐但大量超时」的假数据。
- 用短连接数字套长连接线上流量,严重高估或低估容量。
- 高并发下压测机自身 CPU 先满,误判为服务端瓶颈。
- 每次只压一次、不预热,首轮 JIT/冷缓存结果偏离稳态。
总结
ab 用 -n 总请求数和 -c 并发对单个 URL 快速施压,-k 控制长连接、-p/-T/-H 支持简单 POST;读结果时以 Requests per second 看吞吐、结合 Failed requests 和两个不同口径的 Time per request 综合判断,正确做法是阶梯加压、先预热、同时观测服务端资源并确认压测机没先到瓶颈;复杂场景和尾延迟分位应改用 wrk。