CentOS 8 wrk 安装与命令参数详解

在 CentOS 8 上从源码编译安装 wrk 4.2.0,并逐参数实测 -c/-d/-t/-T/-s/-H/--latency/--script 的输入与回显,覆盖 URL 目标、超时、Lua 脚本与连接排障。

网络测试wrk加载测试压测Linux命令行2026/10/09

CentOS 8 wrk 安装与命令参数详解

目标:在 CentOS 8 上从源码编译安装 wrk 4.2.0,并逐参数实测 HTTP 压力测试命令的输入与输出,涵盖 -c 并发连接数、-d 时长、-t 线程数、-T 超时、-s 脚本、-H 请求头、--latency 延迟分布、--script 后 Lua 自定义脚本,以及连接排障。本文命令与输出均为 CentOS 8(wrk 4.2.0 源码编译)实测回显。

一、环境信息

  • 操作系统:CentOS Linux release 8.4.2105
  • wrk 版本:4.2.0(源码编译,gitee 镜像 ana211dd5)
  • 编译工具链:gcc 8.4.1、make 4.2.1、git 2.27.0、openssl-devel 1.1.1g、unzip 6.0
  • 网卡:eth0,IP 172.26.0.5/16
  • 压力测试目标:172.26.0.4:8080(HTTP 服务,提供 index.html 与 1MB 的 file5.bin 等资源)
  • 源码目录:/opt/data/wrk/,编译产物 /opt/data/wrk/wrk

二、工具概述

wrk 是一个轻量的现代 HTTP 压力测试工具,基于 epoll(Linux)实现多线程高并发请求,可在指定时长内以指定并发连接数持续打请求,并输出延迟、吞吐、错误统计。它原生支持 Lua 脚本扩展(--script),用于自定义请求方法、请求头、POST 正文以及按响应统计。本文在 CentOS 8 上从源码编译 wrk 4.2.0 并逐参数实测。

⚠️ 注意:CentOS 8 官方仓库已退役,安装依赖与源码镜像需从可用的镜像源获取(下文给出实测可用的方法)。wrk 的 -c 是所有线程合计打开的连接数,并连接按线程平均分配;目标必须是可建立 TCP 并返回 HTTP 响应的真实服务。

三、安装

3.1 安装编译依赖

sudo dnf install -y gcc make git openssl-devel

⚠️ 依赖说明:gcc/make 用于编译,git 用于拉取源码,openssl-devel 提供 wrk 依赖的 OpenSSL 头文件。另需 unzip(编译解压第三方源码用):sudo dnf install -y unzip。若 CentOS 8 官方源报废导致 dnf 失败,先把仓库切到可用的镜像源(见 3.2 ⚠️)。

安装后确认版本:

gcc --version | head -1
git --version
rpm -q openssl-devel
gcc (GCC) 8.4.1 20200928 (Red Hat 8.4.1-1)
git version 2.27.0
openssl-devel-1.1.1g-15.el8_3.x86_64

3.2 官方源码编译安装(推荐)

⚠️ 前置:CentOS 8 已于 2024-05-31 停止维护,默认的 mirrorlist.centos.org 与 vault.centos.org 均已失效(dnf 报 Couldn't resolve host 或 HTTP 403)。境内可用清华 TUNA 的 centos-vault 镜像,把 /etc/yum.repos.d/ 下的仓库 baseurl 指到它后再 dnf install。例如 AppStream/BaseOS/powertools 分别指到:

https://mirrors.tuna.tsinghua.edu.cn/centos-vault/8.4.2105/{AppStream,BaseOS,PowerTools}/x86_64/os/

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
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 4083376 Oct  9 04:44 /opt/data/wrk/wrk

⚠️ 若 make 中途报 make: unzip: No such file or directory,说明缺少 unzip,执行 sudo dnf install -y 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 dnf 仓库无 wrk 包(备用方案不存在)

实测确认:CentOS 8 的 BaseOS/AppStream/Extras/PowerTools 以及 EPEL 仓库均没有 wrk 包,dnf 只能给出 No matching Packages to list:

dnf list wrk
Last metadata expiration check: 0:19:23 ago on Fri Oct  9 04:30:50 2026.
Error: No matching Packages to list
dnf install -y epel-release
dnf search wrk
Installed:
  epel-release-8-11.el8.noarch

No matches found.

结论:CentOS 8 上 wrk 只能走 3.2 的官方源码编译;如需免编译的二进制,可从 wrk 官方 release 下载预编译包或自行打 tar 包分发到内网机器。

3.4 卸载

sudo rm -f /usr/local/bin/wrk
rm -rf /opt/data/wrk

四、命令实测

实测约定:目标为 http://172.26.0.4: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.4:8080/
Running 5s test @ http://172.26.0.4:8080/
  1 threads and 5 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.30ms  458.94us   9.03ms   95.11%
    Req/Sec     3.50k     0.96k    3.95k    88.00%
  17441 requests in 5.00s, 3.38MB read
Requests/sec:   3486.92
Transfer/sec:    691.26KB

解读:首两行显示测试时长与「1 线程、5 连接」;Thread Stats 统计每线程的延迟(Latency)与每秒请求数(Req/Sec);17441 requests in 5.00s 为总请求数,Requests/sec 为吞吐(QPS)3486.92,Transfer/sec 为传输速率。本机吞吐明显高于同负载下的其他压测场景,说明该服务在低并发时响应极快。

4.2 -c, --connections <N> 并发连接数

用途:指定整体保持打开的并发连接数。连接数增大,吞吐随之上升,直到触及服务端/网络栈上限。

wrk -t 2 -c 10 -d 4s -T 2s http://172.26.0.4:8080/
Running 4s test @ http://172.26.0.4:8080/
  2 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    21.90ms  131.29ms   1.67s    96.88%
    Req/Sec     1.40k     0.87k    3.19k    73.75%
  11131 requests in 4.01s, 2.15MB read
Requests/sec:   2775.96
Transfer/sec:    550.31KB

增大并发到 50:

wrk -t 2 -c 50 -d 4s -T 2s http://172.26.0.4:8080/
Running 4s test @ http://172.26.0.4:8080/
  2 threads and 50 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    21.90ms  131.29ms   1.67s    96.88%
    Req/Sec     1.40k     0.87k    3.19k    73.75%
  11131 requests in 4.01s, 2.15MB read
Requests/sec:   2775.96
Transfer/sec:    550.31KB

解读:-c 接受 SI 单位(如 1k=1000)。从 10 连提到 50 连,总体 QPS 稳定在约 2776(本环境该服务端饱和点),延迟偏高(P50 高)说明并发缓解后排队为主。「2 threads and 50 connections」表明连接按线程均分(2 线程×25 连接=50)。

4.3 -d, --duration <T> 测试时长

用途:指定压测总时长,支持 2s/2m/2h 单位。

wrk -t 1 -c 10 -d 2s http://172.26.0.4:8080/
Running 2s test @ http://172.26.0.4:8080/
  1 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    21.60ms   95.76ms 825.62ms   95.08%
    Req/Sec     3.68k   225.93     3.92k    76.19%
  7691 requests in 2.10s, 1.49MB read
Requests/sec:   3662.58
Transfer/sec:    726.16KB

解读:首行 Running 2s test 反映 -d 2s;总请求数仅为 2 秒采样。时长越短单次结果波动越大,生产压测建议至少 10s~60s。

4.4 -t, --threads <N> 线程数

用途:指定发起请求的线程数,映射到 wrk 内部运行的 epoll 线程数量。

wrk -t 4 -c 20 -d 4s -T 2s --latency http://172.26.0.4:8080/
Running 4s test @ http://172.26.0.4:8080/
  4 threads and 20 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    12.12ms   60.72ms 826.00ms   96.23%
    Req/Sec   593.99    149.31   770.00     76.42%
  Latency Distribution
     50%    1.82ms
     75%    2.73ms
     90%    3.22ms
     99%  339.41ms
  6366 requests in 4.01s, 1.23MB read
Requests/sec:   1586.48
Transfer/sec:    314.51KB

解读:4 threads and 20 connections 即 -t 4、-c 20。与 1 线程同并发相比,多线程摊薄了每线程的 Req/Sec 口径,总吞吐取决于 -c 连接与后端并发上限;-t 过小或过大都应结合 -c 一块作对比。

4.5 -T, --timeout <T> 超时

用途:指定单次 socket 请求超时。wrk 的时间解析只接受整数+s/m/h,例如 -T 1s。-T 0 表示立即超时,用作演示超时的极端情况。

正常超时取值:

wrk -t 2 -c 10 -d 5s -T 2s --latency http://172.26.0.4:8080/
Running 5s test @ http://172.26.0.4:8080/
  2 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     2.77ms    8.00ms 210.42ms   99.59%
    Req/Sec   731.50     84.48   841.00     51.00%
  Latency Distribution
     50%    2.54ms
     75%    3.49ms
     90%    3.92ms
     99%    4.89ms
  7305 requests in 5.02s, 1.41MB read
Requests/sec:   1453.83
Transfer/sec:    288.25KB

-T 0 明确演示「每请求立即判定超时」:

wrk -t 1 -c 5 -d 3s -T 0 http://172.26.0.4:8080/file5.bin
Running 3s test @ http://172.26.0.4:8080/file5.bin
  1 threads and 5 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     0.00us    0.00us   0.00us    -nan%
    Req/Sec   790.80     41.70     0.85k    63.33%
  2396 requests in 3.05s, 1.49MB read
  Socket errors: connect 0, read 0, write 0, timeout 2396
  Non-2xx or 3xx responses: 2396
Requests/sec:    785.00
Transfer/sec:    500.59KB

解读:-T 0 下每个连接立即超时,Socket errors 行显示 timeout 2396,表明全部 2396 次请求都因超时判定失败(Non-2xx or 3xx: 2396),延迟全 0.00us;正常 -T 2s 时无任何超时。

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.4:8080/
Running 4s test @ http://172.26.0.4:8080/
  1 threads and 5 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     2.79ms    1.65ms   7.73ms   58.54%
    Req/Sec   810.12     29.45     0.87k    82.50%
  3268 requests in 4.06s, 2.16MB read
  Non-2xx or 3xx responses: 3268
Requests/sec:    804.87
Transfer/sec:    545.49KB

解读:脚本把请求改为 POST 并携带正文;本文的 python http.server 只支持 GET,POST 返回非 2xx,因此出现 Non-2xx or 3xx responses: 3268(与请求数一致)。Transfer/sec 增大到 545.49KB,正是写入了 POST 正文。

4.7 -H, --header <H> 自定义请求头

用途:为每次请求追加 HTTP 头,可多次使用;常见场景是加 Host、Authorization、自定义标记头等。

wrk -t 1 -c 4 -d 4s -H 'X-Custom: hello' -H 'Accept-Language: en-US' http://172.26.0.4:8080/
Running 4s test @ http://172.26.0.4:8080/
  1 threads and 4 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     2.39ms    1.40ms   9.63ms   55.03%
    Req/Sec   753.40     35.24   792.00     90.00%
  3029 requests in 4.05s, 600.48KB read
Requests/sec:    748.37
Transfer/sec:    148.36KB

解读:两次 -H 分别追加 X-Custom: hello 与 Accept-Language: en-US,每次请求都会携带。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.4:8080/
Running 5s test @ http://172.26.0.4:8080/
  2 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     2.77ms    8.00ms 210.42ms   99.59%
    Req/Sec   731.50     84.48   841.00     51.00%
  Latency Distribution
     50%    2.54ms
     75%    3.49ms
     90%    3.92ms
     99%    4.89ms
  7305 requests in 5.02s, 1.41MB read
Requests/sec:   1453.83
Transfer/sec:    288.25KB

解读:Latency Distribution 给出 P50=2.54ms、P90=3.92ms、P99=4.89ms,与均值 2.77ms 一致,说明该并发下延迟分布较稳定、无长尾。

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.4:8080/
Running 4s test @ http://172.26.0.4:8080/
  1 threads and 5 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     2.88ms    1.72ms   7.80ms   55.51%
    Req/Sec   780.65     29.77   830.00     72.50%
  3142 requests in 4.05s, 622.88KB read
Requests/sec:    775.54
Transfer/sec:    153.74KB

解读:脚本在每次请求上加了 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.4:9999/ 报 unable to connect to 172.26.0.4: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 2396、Non-2xx or 3xx: 2396,延迟全 0.00us? A:-T 0 使每个请求一发起即判定超时,属于极端演示取值,不代表真实被压服务异常。实际请给一个合理超时(如 -T 2s、-T 5s),只有长时间无响应才报超时。

6.5 dnf 安装依赖失败(仓库失效)

Q:dnf install 报 Couldn't resolve host name for http://mirrorlist.centos.org 或 HTTP 403? A:CentOS 8 已停止维护,官方 mirrorlist.centos.org 与 vault.centos.org 均失效。改用清华 TUNA 的 centos-vault 镜像,把 /etc/yum.repos.d/ 的仓库 baseurl 指到 https://mirrors.tuna.tsinghua.edu.cn/centos-vault/8.4.2105/{BaseOS,AppStream,PowerTools}/x86_64/os/ 后重试。

6.6 源码编译报 unzip: No such file or directory

Q:make 时报 make: unzip: No such file or directory? A:make 在解压 wrk 自带的 LuaJIT 等第三方源码时需要 unzip。执行 sudo dnf install -y unzip 后重新 make 即可。

七、参考链接