Loading...

文章背景图

wrk:现代 HTTP 压测工具编译部署与使用指南

2021-02-07
0
- 字
- 分钟

wrk:现代 HTTP 压测工具编译部署与使用指南

wrk 是一款用 C 编写的现代 HTTP 基准测试(压测)工具。它在单核多路 CPU 上就能产生可观的压力:把多线程设计与 epoll、kqueue 这类可扩展事件通知机制结合,用很少的资源就能打满目标服务。它还可选地通过 LuaJIT 脚本自定义请求生成、响应处理与统计报告,是后端服务上线前做容量评估、接口压测的常用利器。

一、项目官方信息

项目 信息
GitHub 仓库 https://github.com/wg/wrk
主要语言 C(约 96%)
开源协议 Modified Apache 2.0 License(Apache 2.0 修改版)
Star 数 40k+
运行方式 从源码编译出单个二进制 wrk

说明:wrk 官方仓库的 README 与源码中未提供任何 Logo / Banner 图片,故本文不设「官方图片」小节,封面亦不使用占位图,保持与官方素材一致。

二、环境要求

  • 操作系统:类 Unix 系统(Linux、macOS、FreeBSD 等)。
  • 构建工具:GNU make(BSD 上通常是 gmake)与一个 C 编译器(gcc/clang)。
  • 依赖库:wrk 需要 LuaJIT 与 OpenSSL,但它随源码自带了对应版本(deps/LuaJIT-2.1.zip、deps/openssl-1.1.1i.tar.gz),编译时会自动解压并构建,无需你手动安装。
  • 目标侧准备:压测机器要有足够多的临时端口(ephemeral ports)、TIME_WAIT 套接字回收要快;被压服务器的 listen(2) backlog 应大于并发连接数。

三、完整部署(编译)步骤

1. 克隆源码

git clone https://github.com/wg/wrk.git
cd wrk

2. 编译

按照官方 INSTALL 文档,大多数情况下直接运行 make 即可:

make

编译过程会自动解压 deps/ 下的 LuaJIT 与 OpenSSL 并静态构建,最终在当前目录生成可执行文件 wrk。

如果你想改用系统已安装的 LuaJIT / OpenSSL(例如打 OS 发行版包时),可以在 make 时指定路径:

```bash

Linux 使用系统库

make WITH_LUAJIT=/usr WITH_OPENSSL=/usr

macOS 使用 Homebrew 的 OpenSSL

make WITH_OPENSSL=/usr/local/opt/openssl ```

3. 验证安装

查看版本与帮助:

./wrk --version
./wrk --help

能打印出版本号与命令行选项即说明编译成功。可把 wrk 复制到 /usr/local/bin 以便全局调用:

sudo cp wrk /usr/local/bin/

四、使用方法

1. 基础压测

官方 README 给出的标准用法:

wrk -t12 -c400 -d30s http://127.0.0.1:8080/index.html

含义:用 12 个线程、保持 400 个 HTTP 连接打开、持续压测 30 秒,目标是 http://127.0.0.1:8080/index.html。

运行后输出类似:

Running 30s test @ http://127.0.0.1:8080/index.html
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   635.91us    0.89ms  12.92ms   93.69%
    Req/Sec    56.20k     8.07k   62.00k    86.54%
  22464657 requests in 30.00s, 17.76GB read
Requests/sec: 748868.53
Transfer/sec:    606.33MB

重点看最后两行:Requests/sec 是每秒请求数(吞吐),Transfer/sec 是每秒传输流量;中间还给出了平均延迟、标准差与最大延迟。

2. 命令行参数

参数 说明
-c, --connections 保持打开的总 HTTP 连接数,每个线程处理 N = connections/threads 个
-d, --duration 压测时长,如 2s、2m、2h
-t, --threads 使用的总线程数
-s, --script 指定 LuaJIT 脚本(见 SCRIPTING)
-H, --header 为请求添加 HTTP 头,如 "User-Agent: wrk"
--latency 输出详细的延迟统计分布
--timeout 在该时间内未收到响应则记为一次超时

3. 常用组合示例

压测 2 分钟、带详细延迟统计:

wrk -t8 -c200 -d2m --latency http://127.0.0.1:8080/api

给请求加鉴权头:

wrk -t8 -c200 -d30s -H "Authorization: Bearer token123" http://127.0.0.1:8080/api

4. LuaJIT 脚本进阶

仓库 scripts/ 目录自带多个示例脚本:post.lua(POST 请求)、auth.lua(鉴权)、counter.lua、delay.lua、pipeline.lua、report.lua、setup.lua、stop.lua、addr.lua。用 -s 指定即可,例如发 POST:

wrk -t8 -c200 -d30s -s scripts/post.lua http://127.0.0.1:8080/

官方提示:只改 HTTP 方法、路径、请求头或 body 的脚本对性能几乎无影响;但每个请求都重新构造请求、或使用 response() 处理响应,会明显降低能产生的压力。

五、常见问题 FAQ

Q1:编译时报错缺少 make / gcc? 请先安装构建工具链(如 Debian/Ubuntu 上 sudo apt install build-essential)。wrk 自带了 LuaJIT 与 OpenSSL 源码,正常不需要额外安装这两个库。

Q2:为什么压测吞吐上不去、客户端先到瓶颈? README 提醒:压测机要有足够的临时端口、关闭的套接字要能快速回收;线程数一般建议不超过 CPU 核心数的 2 倍,连接数再按需调大。

Q3:压测时被压服务大量报错? 说明服务的 listen(2) backlog 小于并发连接数,初始连接突发时被丢弃。请调大服务端 backlog 后再测。

Q4:-c 和 -t 怎么配? -t 是线程数(通常按 CPU 核数取 2~4 倍即可),-c 是总并发连接数,每个线程分摊 connections/threads 个。二者要一起设置,单独调大其一没有意义。

Q5:能压测 HTTPS 接口吗? 可以。wrk 编译时静态链接了 OpenSSL,直接把目标 URL 写成 https:// 即可。

Q6:为什么用 Lua 脚本后吞吐下降? 官方说明:每请求动作(尤其是新建 HTTP 请求、用 response() 处理响应)会消耗 CPU,从而压低可生成的压力;只做静态字段改写的脚本无性能损耗。

六、跳转链接

评论交流

文章目录