wrk的一个小小小教程

目录


安装

sh 复制代码
# macOS homebrew
brew install wrk

# version
wrk -v

wrk 仅支持 Linux/macOS,不支持 Windows。建议在 Linux 服务器上跑压测,结果更准确。

基本用法

基本命令格式

sh 复制代码
wrk [options] <url>

最简单的压测命令(3个核心参数):

sh 复制代码
wrk -t8 -c400 -d30s http://localhost:8080/api/link
  • -t, threads

    线程数,通常设为 CPU 核心数。

    推荐:nproc(Linux), sysctl -n hw.logicalcpu(macOS) 查看核心数

  • -c, connections

    并发连接数,总连接 = c

    每线程连接 = c / t

  • -d, duration

    测试持续时间

    30s / 2m / 1h

连接数

经验公式:连接数 = 线程数 × (目标QPS / 单线程QPS估算)

通常从 -t4 -c100 开始,逐步增加 -c 直到 QPS 不再增长,此时即为服务瓶颈。

读懂输出

sh 复制代码
# 运行命令 
wrk -t12 -c400 -d30s http://localhost:8080/link/test

# 输出
Running 30s test @ http://localhost:8080/link/test
  12 threads and 400 connections		# 压测配置,12个线程,400个并发连接

  # 线程级统计:平均值、标准差、最大值、符合标准差范围的请求占比
  Thread Stats   Avg      Stdev     Max    +/- Stdev	
    Latency    16.72ms   3.21ms  89.44ms   91.23%		# 延迟:平均16ms, 波动3ms,最大89ms,有91.23%的请求在均值±标准差范围内
    Req/Sec  2.09k   312.54    3.12k    68.45%		# 每秒请求数:单线程平均2.09k,波动 321.54,峰值3.12k,68%的请求在均值±标准差范围内

  # 延迟分布(分位数,核心用户体验指标) 
  Latency Distribution	
     50%    13.03ms		# 中位数:50%的请求延迟≤13.03ms
     75%    17.86ms		
     90%    24.15ms
     99%    38.92ms		# 99%的请求延迟 ≤ 38.92ms(重点:仅1%请求超过272ms)

  754238 requests in 30.01s, 124.47MB read		# 30s内共处理的请求数以及读取数据大小
 Requests/sec:  25114.21		# QPS:核心吞吐量,平均每秒处理请求数
 Transfer/sec:   4.14MB			# 数据传输量:平均每秒传输的数据量
字段 含义 关注点
Latency Avg 平均延迟 反映正常情况下的响应速度
Latency Stdev 延迟标准差 越小越稳定,大说明抖动严重
Latency Max 最大延迟 极端情况,关注是否超时
50%(P50) 中位数延迟 50% 请求在此时间内完成
99%(P99) 长尾延迟 最重要!生产关注 P99
Requests/sec QPS 核心指标,越高越好
Transfer/sec 吞吐量 带宽占用参考

注意:输出中若出现 Socket errors 或 Non-2xx 行,说明有连接失败或服务端报错,此时 QPS 数据不可信!

sh 复制代码
# 问题输出示例(需要排查)
Socket errors: connect 0, read 12, write 0, timeout 24
Non-2xx or 3xx responses: 1024

Lua 脚本

wrk 支持 Lua 脚本实现:自定义请求头、POST Body、动态参数、响应处理等。

1. POST JSON 请求

lua 复制代码
-- post.lua
wrk.method = "POST"
wrk.body   = '{"originUrl":"https://www.google.com","gid":"test001"}'
wrk.headers["Content-Type"] = "application/json"
wrk.headers["Authorization"] = "Bearer eyJhbGciOiJ..."
sh 复制代码
wrk -t8 -c200 -d30s -s post.lua http://localhost:8080/api/link/create

2. 动态参数(随机化请求)

lua 复制代码
-- random_param.lua
math.randomseed(os.time())

-- 每次请求前调用,修改请求路径
request = function()
  local suffix = math.random(1, 100000)
  local path   = "/link/" .. suffix
  return wrk.format("GET", path)
end

3. 统计响应(done 钩子)

lua 复制代码
-- stats.lua
local counter = 0
local errors  = 0

response = function(status, headers, body)
  counter = counter + 1
  if status ~= 200 then
    errors = errors + 1
  end
end

done = function(summary, latency, requests)
  io.write("Total requests: " .. counter .. "\n")
  io.write("Error responses: " .. errors .. "\n")
  io.write("P99 latency: " 
    .. latency:percentile(99) / 1000 .. "ms\n")
end

4. 可用的 Lua 钩子函数

函数 触发时机 用途
setup(thread) 每个线程启动时 初始化线程私有数据
init(args) 线程开始前 解析命令行参数
request() 每次发请求前 动态构造请求
response(s,h,b) 收到响应后 处理/统计响应
done(sum,lat,req) 测试结束 自定义输出统计

参数详解

参数 说明 示例
-t N 线程数 -t 8
-c N 并发连接数 -c 400
-d T 持续时间 -d 30s / -d 2m
-s file Lua 脚本路径 -s post.lua
--latency 输出延迟分布(P50/P75/P90/P99) --latency
--timeout T 请求超时时间 --timeout 5s
-H "header" 添加请求头 -H "Authorization: Bearer xxx"
--version 查看版本 --version

推荐固定加上 --latency,默认输出不含延迟分布,这个参数让你看到 P50/P75/P90/P99。

sh 复制代码
# 添加请求头
wrk -t8 -c200 -d30s --latency \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your_token" \
  http://localhost:8080/api/link/abc123

场景示例

短链重定向(GET)

sh 复制代码
# 基准测试 - 不带缓存
wrk -t8 -c200 -d30s --latency \
  http://localhost:8080/link/abc123
  
# 对比:开启 Caffeine 本地缓存后
wrk -t8 -c200 -d30s --latency \
  http://localhost:8080/link/abc123

你之前跑出的数据:baseline QPS ~23,896 / P99 13.03ms → Caffeine 后 QPS ~25,114 / P99 5.69ms(P99 降低 56%)

带 Token 的 API 接口

sh 复制代码
wrk -t8 -c100 -d30s --latency \
  -H "Authorization: Bearer eyJ..." \
  -H "Content-Type: application/json" \
  http://localhost:8080/api/user/info

POST 创建接口(Lua 脚本)

sh 复制代码
# 先创建 create_link.lua
cat > create_link.lua << 'EOF'
wrk.method = "POST"
wrk.body   = '{"originUrl":"https://example.com","gid":"gid001"}'
wrk.headers["Content-Type"] = "application/json"
wrk.headers["Authorization"] = "Bearer your_token"
EOF

# 运行
wrk -t4 -c50 -d30s --latency \
  -s create_link.lua \
  http://localhost:8080/api/link/create

逐步加压找瓶颈

sh 复制代码
# 梯度压测脚本
for c in 50 100 200 400 800; do
  echo "--- 并发连接: $c ---"
  wrk -t8 -c$c -d15s --latency \
    http://localhost:8080/link/test
  sleep 5
done

当 QPS 不再随 -c 增长甚至下降时,即为当前配置的性能上限。

推荐配置

  1. 本机测试

    sh 复制代码
    wrk -t$(sysctl -n hw.logicalcpu) -c200 \
      	-d30s --latency \
    	http://localhost:8080/
  2. 远程服务

    sh 复制代码
    wrk -t4 -c100 \
    	-d30s --timeout 5s \
    	--latency http://s.xmon.me/
相关推荐
雪碧聊技术1 个月前
什么是压力测试?压力测试的工具有哪些?一文详解
jmeter·压力测试·wrk
雪碧聊技术2 个月前
压力测试工具wrk安装、使用
wrk·压测工具·安装、使用wrk
qyvlik9 个月前
MacOS 使用 luarocks+wrk+luajit
macos·lua·wrk
恋喵大鲤鱼2 年前
wrk(1) command
wrk
todoitbo2 年前
掌握wrk压力测试工具的优化技巧与实践
测试工具·压力测试·wrk
路过秋天2 年前
Taurus.MVC 性能压力测试(ap 压测 和 linux 下wrk 压测):.NET Core 版本
wrk·taurus.mvc·ab·性能压力测试
FeelTouch Labs2 年前
Wrk压测发送Post请求的正确姿势
wrk
生生世世是所说的3 年前
web api性能测试使用wrk
wrk·web性能测试