Ubuntu 22.04 wrk 安装与命令参数详解
在 Ubuntu 22.04 上从源码编译安装 wrk 4.2.0,并逐参数实测 -c/-d/-t/-T/-s/-H/--latency/--script 的输入与回显,覆盖 URL 目标、超时、Lua 脚本与排障。
Ubuntu 22.04 wrk 安装与命令参数详解
目标:在 Ubuntu 22.04 上从源码编译安装 wrk 4.2.0,并逐参数实测 HTTP 压力测试命令的输入与输出,涵盖
-c并发连接数、-d时长、-t线程数、-T超时、-s脚本、-H请求头、--latency延迟分布、--script后 Lua 自定义脚本,以及连接排障。本文命令与输出均为 Ubuntu 22.04(wrk 4.2.0 源码编译)实测回显。
一、环境信息
- 操作系统:Ubuntu 22.04.5 LTS(Jammy Jellyfish)
- wrk 版本:4.2.0(源码编译,gitee 镜像 ana211dd5)
- 编译工具链:gcc 11.4.0、make 4.3、git 2.34.1、libssl-dev 3.0.2、unzip 6.0
- 网卡:eth0,IP
172.26.0.3/16 - 压力测试目标:
172.26.0.2:8080(HTTP 服务,提供 index.html 与 1MB 的 file5.bin 等资源) - 源码目录:
/opt/data/wrk/,编译产物/opt/data/wrk/wrk
二、工具概述
wrk 是一个轻量的现代 HTTP 压力测试工具,基于 epoll(Linux)实现多线程高并发请求,可在指定时长内以指定并发连接数持续打请求,并输出延迟、吞吐、错误统计。它原生支持 Lua 脚本扩展(--script),用于自定义请求方法、请求头、POST 正文以及按响应统计。本文在 Ubuntu 22.04 上从源码编译 wrk 4.2.0 并逐参数实测。
⚠️ 注意:wrk 的
-c是所有线程合计打开的连接数,并非每线程连接数;连接按线程平均分配。wrk 只做 HTTP 压测,目标必须是可建立 TCP 并返回 HTTP 响应的真实服务。
三、安装
3.1 安装编译依赖
sudo apt update
sudo apt install -y build-essential libssl-dev git unzip
💡 依赖说明:
build-essential提供 gcc 与 make;libssl-dev提供 wrk 依赖的 OpenSSL 头文件与库;git用于拉取源码;unzip用于解压 wrk 自带的 LuaJIT/OpenSSL 第三方源码(make过程会用到)。
安装后确认版本:
gcc --version | head -1
git --version
dpkg -l libssl-dev | tail -1
gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0
git version 2.34.1
ii libssl-dev:amd64 3.0.2-0ubuntu1.30 amd64 Secure Sockets Layer toolkit - development files
3.2 官方源码编译安装(推荐)
wrk 托管在 GitHub 的 wg/wrk 仓库。在内网/境内网络直连 github.com 拉取不稳时,可用其 gitee.com/mirrors/wrk 镜像(仅镜像关系,代码与官方一致),克隆后 make 即可。以下为实测命令:
cd /opt/data/
git clone https://gitee.com/mirrors/wrk.git
ls -d /opt/data/wrk
cd wrk
make
/opt/data/wrk
echo LuaJIT-2.1
LuaJIT-2.1
CC src/wrk.c
CC src/net.c
CC src/ssl.c
CC src/aprintf.c
CC src/stats.c
CC src/script.c
CC src/units.c
CC src/ae.c
CC src/zmalloc.c
CC src/http_parser.c
LUAJIT src/wrk.lua
cc -std=c99 -Wall -O2 -D_REENTRANT -D_POSIX_C_SOURCE=200112L -D_BSD_SOURCE -D_DEFAULT_SOURCE -Iobj/include -Iobj/include/luajit-2.1 -c -o obj/bytecode.o obj/bytecode.c
LINK wrk
编译产物:
ls -l /opt/data/wrk/wrk
-rwxr-xr-x 1 root root 4412024 Oct 9 04:38 /opt/data/wrk/wrk
⚠️ 若
make中途报make: unzip: No such file or directory,说明缺少 unzip,按 3.1 安装unzip后重新make即可。
把二进制放入 PATH 方便直接调用:
sudo cp /opt/data/wrk/wrk /usr/local/bin/
wrk --version
wrk 4.2.0 [epoll] Copyright (C) 2012 Will Glozer
3.3 apt 仓库安装(备用)
Ubuntu 22.04 的官方仓库自带 wrk(版本 4.1.0,略旧于 4.2.0),无需编译即可使用:
sudo apt install -y wrk
wrk --version
wrk debian/4.1.0-3build1 [epoll] Copyright (C) 2012 Will Glozer
which -a wrk
/usr/local/bin/wrk
/usr/bin/wrk
/bin/wrk
💡 两版并存时,
/usr/local/bin优先级高于/usr/bin,默认调用的是源码编译的 4.2.0;若想用仓库版,显式调用/usr/bin/wrk。备用方案适合不想编译的场景,但版本旧于源码版。
3.4 卸载
sudo rm -f /usr/local/bin/wrk
sudo apt purge -y wrk
rm -rf /opt/data/wrk
四、命令实测
实测约定:目标为 http://172.26.0.2:8080/(HTTP 服务,返回 200 与 index.html 内容)。文中输出均为逐条真实回显。
4.1 URL 目标(基础用法)
用途:wrk <选项> <url>,url 为 HTTP 压测目标,必填。
wrk -t 1 -c 5 -d 5s -T 2s http://172.26.0.2:8080/
Running 5s test @ http://172.26.0.2:8080/
1 threads and 5 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 6.64ms 2.14ms 20.25ms 76.27%
Req/Sec 746.40 74.77 0.88k 74.00%
3715 requests in 5.00s, 743.91KB read
Requests/sec: 742.97
Transfer/sec: 148.77KB
解读:首两行显示测试时长与「1 线程、5 连接」;Thread Stats 统计每线程的延迟(Latency)与每秒请求数(Req/Sec)的均值/标准差/最大值;随后 3715 requests in 5.00s 表示总请求数;Requests/sec 为吞吐(QPS),Transfer/sec 为网络传输速率。数据无 Socket errors/Non-2xx 行,说明所有请求均成功且返回 2xx。
4.2 -c, --connections <N> 并发连接数
用途:指定整体保持打开的并发连接数。连接数增大,吞吐通常先升后达到上限(取决于服务端与网络栈)。
wrk -t 2 -c 10 -d 5s -T 2s http://172.26.0.2:8080/
Running 5s test @ http://172.26.0.2:8080/
2 threads and 10 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 8.22ms 2.97ms 38.23ms 74.89%
Req/Sec 377.78 142.49 666.00 68.00%
3763 requests in 5.01s, 753.33KB read
Requests/sec: 751.61
Transfer/sec: 150.47KB
增大到 20 连接、4 线程:
wrk -t 4 -c 20 -d 5s -T 2s http://172.26.0.2:8080/
Running 5s test @ http://172.26.0.2:8080/
4 threads and 20 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 36.46ms 143.87ms 1.67s 95.57%
Req/Sec 199.00 123.04 580.00 77.84%
3513 requests in 5.01s, 703.47KB read
Socket errors: connect 0, read 0, write 0, timeout 1
Requests/sec: 701.05
Transfer/sec: 140.38KB
解读:-c 接受 SI 单位(如 1k = 1000)。本机能力有限,并发从 5 提到 10、20 后总体 QPS 反而微降且有 1 次超时,说明已达到该服务端软并发上限。「2 threads and 10 connections」字面表明连接是按 -c/线程数 均分的(2 线程×5 连接=10)。
4.3 -d, --duration <T> 测试时长
用途:指定压测总时长,支持 2s/2m/2h 单位。
wrk -t 1 -c 10 -d 2s http://172.26.0.2:8080/
Running 2s test @ http://172.26.0.2:8080/
1 threads and 10 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 7.83ms 2.21ms 22.47ms 72.85%
Req/Sec 764.10 43.77 818.00 75.00%
1521 requests in 2.00s, 304.50KB read
Requests/sec: 760.40
Transfer/sec: 152.23KB
解读:首行 Running 2s test 反映 -d 2s;总请求数与时长成正比缩减。时长越短单次结果波动越大,生产压测建议至少 10s~60s。
4.4 -t, --threads <N> 线程数
用途:指定发起请求的线程数,映射到 wrk 内部运行的 epoll 线程数量。
wrk -t 4 -c 20 -d 5s -T 2s --latency http://172.26.0.2:8080/
Running 5s test @ http://172.26.0.2:8080/
4 threads and 20 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 36.46ms 143.87ms 1.67s 95.57%
Req/Sec 199.00 123.04 580.00 77.84%
3513 requests in 5.01s, 703.47KB read
Socket errors: connect 0, read 0, write 0, timeout 1
Requests/sec: 701.05
Transfer/sec: 140.38KB
解读:4 threads 即 -t 4。线程数增加会放大每线程的 Req/Sec 统计口径(这里是并行 4 路),总吞吐取决于 -c 连接与目标并发上限;-t 过多在小并发下无明显收益。
4.5 -T, --timeout <T> 超时
用途:指定单次 socket 请求超时。wrk 的时间解析只接受整数+s/m/h,例如 -T 1s。-T 0 表示立即超时,用作演示超时的极端情况。
正常超时取值:
wrk -t 2 -c 20 -d 5s -T 1s --latency http://172.26.0.2:8080/
Running 5s test @ http://172.26.0.2:8080/
2 threads and 20 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 21.44ms 78.81ms 836.40ms 96.40%
Req/Sec 423.97 162.84 0.90k 84.09%
Latency Distribution
50% 7.87ms
75% 9.90ms
90% 12.86ms
99% 508.32ms
3734 requests in 5.00s, 747.71KB read
Socket errors: connect 0, read 0, write 0, timeout 4
Requests/sec: 746.12
Transfer/sec: 149.41KB
-T 0 明确演示「每请求立即判定超时」:
wrk -t 1 -c 5 -d 3s -T 0 --latency http://172.26.0.2:8080/file5.bin
Running 3s test @ http://172.26.0.2:8080/file5.bin
1 threads and 5 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 0.00us 0.00us 0.00us -nan%
Req/Sec 0.91k 68.69 0.99k 80.00%
Latency Distribution
50% 0.00us
75% 0.00us
90% 0.00us
99% 0.00us
2720 requests in 3.00s, 1.70MB read
Socket errors: connect 0, read 0, write 0, timeout 2720
Non-2xx or 3xx responses: 2720
Requests/sec: 906.57
Transfer/sec: 579.88KB
解读:-T 0 下每个连接都立即超时,Socket errors 行显示 timeout 2720,表明全部 2720 次请求都因超时被判定失败(Non-2xx or 3xx: 2720),延迟全为 0.00us。正常 -T 1s 时偶发 timeout 4,即个别慢请求被判定超时。
4.6 -s, --script <S> 使用官方脚本
用途:加载 wrk 自带的 Lua 脚本(位于 scripts/ 目录),如 post.lua 把默认请求改成 POST,并追加 POST 正文与 Content-Type。
查看脚本内容:
cat /opt/data/wrk/scripts/post.lua
-- example HTTP POST script which demonstrates setting the
-- HTTP method, body, and adding a header
wrk.method = "POST"
wrk.body = "foo=bar&baz=quux"
wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"
用 -s 加载执行:
wrk -t 1 -c 5 -d 4s -s /opt/data/wrk/scripts/post.lua http://172.26.0.2:8080/
Running 4s test @ http://172.26.0.2:8080/
1 threads and 5 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 5.18ms 2.93ms 41.44ms 68.60%
Req/Sec 528.80 56.41 611.00 77.50%
2137 requests in 4.07s, 1.42MB read
Non-2xx or 3xx responses: 2137
Requests/sec: 525.35
Transfer/sec: 357.08KB
解读:脚本把请求方法改为 POST 并携带正文;本文的 python http.server 只支持 GET,POST 返回非 2xx,因此出现 Non-2xx or 3xx responses: 2137(与请求数一致)。Transfer/sec 增大到 357.08KB,正是写入了 POST 正文。这从实测说明:-s 可改变请求体行为,且 Non-2xx 计入错误统计。
4.7 -H, --header <H> 自定义请求头
用途:为每次请求追加 HTTP 头,可多次使用;常见场景是加 Host、Authorization、自定义标记头等。
wrk -t 1 -c 4 -d 4s -H 'X-Custom: hello' -H 'Accept-Language: zh-CN' http://172.26.0.2:8080/
Running 4s test @ http://172.26.0.2:8080/
1 threads and 4 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 5.64ms 2.61ms 18.62ms 66.76%
Req/Sec 431.95 125.93 820.00 85.00%
1739 requests in 4.05s, 348.14KB read
Requests/sec: 429.49
Transfer/sec: 85.98KB
解读:两次 -H 分别追加 X-Custom: hello 与 Accept-Language: zh-CN,每次请求都会携带。wrk 默认会自动添加 Connection: keep-alive 以复用连接。
4.8 --latency 延迟分布
用途:在输出中追加 Latency Distribution(延迟百分位分布),用于评估延迟的 P50/P75/P90/P99。
wrk -t 2 -c 10 -d 5s -T 2s --latency http://172.26.0.2:8080/
Running 5s test @ http://172.26.0.2:8080/
2 threads and 10 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 8.67ms 8.88ms 221.88ms 98.62%
Req/Sec 376.44 169.53 680.00 65.00%
Latency Distribution
50% 7.72ms
75% 9.32ms
90% 11.10ms
99% 19.20ms
3748 requests in 5.00s, 750.51KB read
Requests/sec: 749.15
Transfer/sec: 150.01KB
解读:Latency Distribution 给出 50%/75%/90%/99% 响应延迟:P50=7.72ms、P90=11.10ms、P99=19.20ms。P99 远高于均值(8.67ms),说明存在少量长尾请求。
4.9 --script 后自写 Lua 脚本
用途:--script 是 -s 的长选项写法;这里演示用自写 Lua 脚本同时「自定义请求头 + 统计非 200 响应」。新建脚本:
cat > /opt/data/wrk/myscript.lua <<'EOF'
-- 自定义 wrk Lua 脚本:自定义请求头 + 响应状态统计
wrk.method = "GET"
wrk.headers["X-My-Test"] = "wrk-custom"
wrk.headers["Connection"] = "keep-alive"
function response(status, headers, body)
if status ~= 200 then
io.write("non-200 status: " .. status .. "\n")
end
end
EOF
用 --script 加载执行:
wrk -t 1 -c 5 -d 4s --script /opt/data/wrk/myscript.lua http://172.26.0.2:8080/
Running 4s test @ http://172.26.0.2:8080/
1 threads and 5 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 6.53ms 2.41ms 24.84ms 75.01%
Req/Sec 679.20 131.96 830.00 72.50%
2710 requests in 4.01s, 542.89KB read
Requests/sec: 675.34
Transfer/sec: 135.29KB
解读:脚本在每次请求上加了 X-My-Test: wrk-custom 头;由于目标全部返回 200,response() 未打印任何 non-200 status 行。脚本框架可扩展为会话级随机参数(request())、按状态码统计等,wrk 的 Lua API 提供 wrk.method、wrk.headers、wrk.body、request()、response()、done() 等钩子。
五、帮助输出
5.1 wrk --help(帮助全文)
wrk 未注册 --help 名目,不带参数或参数解析失败即打印以下使用说明:
Usage: wrk <options> <url>
Options:
-c, --connections <N> Connections to keep open
-d, --duration <T> Duration of test
-t, --threads <N> Number of threads to use
-s, --script <S> Load Lua script file
-H, --header <H> Add header to request
--latency Print latency statistics
--timeout <T> Socket/request timeout
-v, --version Print version details
Numeric arguments may include a SI unit (1k, 1M, 1G)
Time arguments may include a time unit (2s, 2m, 2h)
💡 直接运行
wrk(无参数)即打印上述帮助,RC=1。Numeric arguments may include a SI unit (1k, 1M, 1G)说明-c等数值参数可写1k;Time arguments may include a time unit (2s, 2m, 2h)说明-d/-T时间参数需带s/m/h单位。
5.2 版本查询
wrk --version
wrk 4.2.0 [epoll] Copyright (C) 2012 Will Glozer
💡
4.2.0为版本号,[epoll]表明当前使用 Linux epoll 事件模型。
六、常见问题
6.1 连接目标必须是真实 HTTP 服务
Q:wrk http://172.26.0.2:9999/ 报 unable to connect to 172.26.0.2:9999 Connection refused?
A:9999 端口无服务监听。wrk 必须能对被试地址建立 TCP 连接;若无监听或端口未开放,直接报 unable to connect to <IP>:<port> Connection refused,RC=1。请先确认目标进程在监听且端口可达,再压测。
6.2 目标只会响应 TCP、不返回 HTTP 会怎样
Q:压测一个只开了 TCP 监听、不返回 HTTP 的端口(如某些内部服务)会怎样? A:wrk 会正常建立连接、发起 HTTP 请求,但因收不到可解析的 HTTP 响应,请求全部失败、最终无有效流量:
Running 3s test @ http://172.26.0.4:8082/
1 threads and 2 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 0.00us 0.00us 0.00us -nan%
Req/Sec 0.00 0.00 0.00 -nan%
0 requests in 3.00s, 0.00B read
Requests/sec: 0.00
Transfer/sec: 0.00B
解读:0 requests in 3.00s 说明连接虽建立但无一次请求被统计为成功,需为目标提供真实 HTTP 服务(如 nginx、python3 -m http.server 等)后再压测。
6.3 时间参数为何不能写毫秒
Q:-T 1ms 或 -T 0.001s 为什么直接打印帮助、没有进入压测?
A:wrk 的时间解析只接受「整数 + s/m/h」单位,毫秒/小数不合法(0 合法)。传入非法时间值会由参数解析直接失败并打印 usage、不发起压测。需要极小超时可用 -T 0(立即超时,用于演示)。
6.4 全部请求都 timeout
Q:-T 0 压测时输出 timeout 2720、Non-2xx or 3xx: 2720,延迟全 0.00us?
A:-T 0 使每个请求一发起即判定超时,属于极端演示取值,不代表真实被压服务异常。实际请给一个合理超时(如 -T 2s、-T 5s),只有长时间无响应才报超时。
6.5 源码编译报 unzip: No such file or directory
Q:make 时报 make: unzip: No such file or directory?
A:make 在解压 wrk 自带的 LuaJIT 等第三方源码时需要 unzip。执行 sudo apt install -y unzip 后重新 make 即可。
6.6 Post 请求为何出现 Non-2xx or 3xx
Q:用 post.lua 压测出现 Non-2xx or 3xx responses: 2137?
A:wrk 把 POST 发给了仅支持 GET 的 http.server,目标返回 405/501 等非 2xx 状态,逐条计入该字段。压测接口时若预期返回非 2xx(如 4xx/5xx),wrk 仍会统计请求,但会显著拉低有效吞吐口径。
七、参考链接
- wrk 官方 GitHub 仓库:https://github.com/wg/wrk
- wrk 境内镜像(本文实测克隆源):https://gitee.com/mirrors/wrk
- wrk 官方 README 与 Lua 脚本接口说明:https://github.com/wg/wrk/blob/master/README.md
- 本文素材来源:Ubuntu 22.04 实测采集(wrk 4.2.0 源码编译,目标 HTTP 服务 8080)