ab —— 最简单的 HTTP 压测
ab —— 最简单的 HTTP 压测
分类:10 压测与基准 适用:ApacheBench(
apache2-utils/httpd-tools),所有 Linux 一句话:一条命令测出接口每秒能扛多少请求,适合快速摸底,不适合精细压测。
1. 它解决什么问题
- 接口上线前想知道大概能扛多少 QPS。
- 改完配置(连接池、worker 数)做前后对比。
- 验证压测环境与链路是否通。
不适合:长连接高并发、HTTP/2、需要脚本化场景的压测(用 wrk/k6/jmeter)。
2. 安装
apt install -y apache2-utils
dnf install -y httpd-tools
3. 基本用法
ab -n 1000 -c 10 http://127.0.0.1:8080/health
-n总请求数-c并发数(同时进行的请求)
# 带 KeepAlive
ab -n 10000 -c 100 -k http://127.0.0.1:8080/
# 按时间压测(替代 -n)
ab -t 30 -c 50 -k http://127.0.0.1:8080/
# POST JSON
ab -n 1000 -c 20 -p payload.json -T application/json http://127.0.0.1:8080/api
# 带 Header / Cookie
ab -n 1000 -c 20 -H 'Authorization: Bearer xxx' -H 'X-Env: test' http://...
ab -n 100 -c 5 -C 'sessionid=abc123' http://...
# Basic Auth
ab -n 100 -c 5 -A user:pass http://...
# 输出 CSV(每个请求的耗时)
ab -n 1000 -c 10 -e /tmp/result.csv http://...
# 输出 gnuplot 格式(便于画图)
ab -n 1000 -c 10 -g /tmp/result.tsv http://...
4. 结果怎么读
Concurrency Level: 100
Time taken for tests: 12.345 seconds
Complete requests: 10000
Failed requests: 3
(Connect: 0, Receive: 0, Length: 3, Exceptions: 0)
Non-2xx responses: 20
Total transferred: 12345678 bytes
HTML transferred: 9876543 bytes
Requests per second: 810.05 [#/sec] (mean)
Time per request: 123.456 [ms] (mean)
Time per request: 1.235 [ms] (mean, across all concurrent requests)
Transfer rate: 976.12 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 1 0.5 1 10
Processing: 20 110 35.2 98 450
Waiting: 15 100 34.1 90 430
Total: 21 111 35.3 99 460
Percentage of the requests served within a certain time (ms)
50% 99
66% 120
75% 135
80% 150
90% 190
95% 230
99% 420
100% 460 (longest request)
| 指标 | 关注点 |
|---|---|
Requests per second |
吞吐量,核心指标 |
Time per request(第一个) |
单请求平均耗时(含排队) |
Time per request(第二个) |
所有并发平均,数值小很多,别混淆 |
Failed requests |
非 0 必须排查(连接失败、长度不一致、超时) |
Non-2xx responses |
业务错误,ab 不算它"失败" |
Connect / Processing / Waiting |
连接、处理、首字节等待 |
| 百分位表 | P95/P99 才是用户体验,平均值会骗人 |
关键判读
Non-2xx > 0:压测结果无效,先修服务。Failed requests (Length):响应长度不一致,通常是服务端异常返回。Connect时间高:TCP 握手慢,可能是-k没开或somaxconn小。Waiting高:服务端处理慢,不是网络问题。- 并发升到某点 QPS 不再涨、P99 暴涨:到了容量拐点。
5. 压测方法(避免自欺欺人)
# 1. 先单请求确认功能正常
curl -s -o /dev/null -w '%{http_code} %{time_total}\n' http://target/health
# 2. 阶梯加压,找拐点
for c in 10 50 100 200 400; do
echo "== c=$c"
ab -n $((c*200)) -c $c -k http://target/api 2>&1 | grep -E 'Requests per second|Time per request|Failed|Non-2xx'
done
记录每档的 QPS 与 P99,画出来就能看到拐点。
6. 实战场景
6.1 前后对比(改配置验证效果)
# 改之前
ab -n 5000 -c 100 -k http://127.0.0.1:8080/api > /tmp/before.txt
# 改 worker/连接池之后
ab -n 5000 -c 100 -k http://127.0.0.1:8080/api > /tmp/after.txt
diff <(grep -E 'Requests per second|Time per request' /tmp/before.txt) \
<(grep -E 'Requests per second|Time per request' /tmp/after.txt)
6.2 验证 KeepAlive 是否生效
# 不开 -k
ab -n 5000 -c 100 http://127.0.0.1:8080/api
# 开 -k
ab -n 5000 -c 100 -k http://127.0.0.1:8080/api
不开 KeepAlive 会大量出现 TIME_WAIT,QPS 明显更低。若开 -k 后没提升,说明 Nginx/后端没启用长连接(keepalive 指令、Connection 头)。
6.3 压测时同步观察服务端
# 压测机
ab -n 20000 -c 200 -k http://target/api &
# 服务端
watch -n1 'ss -s; echo; vmstat 1 2 | tail -1'
看 TIME_WAIT、ESTAB、sy、wa 是否异常。QPS 上不去往往是 somaxconn、文件描述符、连接池打满。
6.4 使用 POST 压测
cat > /tmp/body.json <<'EOF'
{"userId":123,"action":"query"}
EOF
ab -n 2000 -c 50 -p /tmp/body.json -T application/json \
-H 'Content-Type: application/json' http://target/api/query
7. 常见坑
-n太小:-n 100的结果没统计意义,至少几千。-c大于-n:ab 会报错或结果异常。- 压测机自己成瓶颈:ab 是单线程,高并发下客户端 CPU 先满,测的是 ab 不是服务端。
- 本机压本机:网络栈、CPU 争抢导致数据失真,尽量跨机。
- 不支持 HTTP/2:对 HTTP/2 服务只能用 HTTP/1.1 压,结果偏低。
-k与Connection: close冲突:服务端强制关闭时 KeepAlive 无效。Non-2xx不算失败:看Failed requests为 0 就以为成功,其实全是 500。- DNS 解析开销:用域名压测时每个连接可能重新解析,用 IP 或
-H 'Host: ...'。 Time per request看错:第一个是单请求(含排队),第二个是并发平均,报告里要说明用哪个。- 压测影响生产:绝不对生产直接压,除非有预案和限流。
- 没预热:JIT/连接池/缓存冷启动,前几秒数据偏低,先跑一轮丢弃。
-t与-n同时用:-t优先,-n被忽略。
8. 速查表
ab -n 1000 -c 10 <url>
ab -n 10000 -c 100 -k <url> # KeepAlive(推荐)
ab -t 30 -c 50 -k <url> # 按时长
ab -n 1000 -c 20 -p body.json -T application/json <url>
ab -n 1000 -c 20 -H 'Authorization: Bearer x' <url>
ab -n 1000 -c 20 -e /tmp/out.csv <url>
ab -n 1000 -c 10 -g /tmp/plot.tsv <url> # gnuplot
# 关注
Requests per second # QPS
Time per request # 延迟
Failed requests # 必须为 0
Non-2xx responses # 必须为 0
P95 / P99 # 真实体验