学习使用wrk进行压力测试

发布 : 2023-08-30

根据官方示例,其实 wrk 最大的特点是支持动态脚本修改请求,本身不大的身体集成了 luajit 用于实施请求时动态修改请求/响应。

安装

Windows

由于wrk依赖的一些特性在Windows上没有,因此不支持在windows上编译运行,编译成功也会有一些奇怪的问题。因此建议曲线使用,在 docker 中编译, 借助docker在windows上使用。

MacOS
  1. brew install wrk
  2. 源码安装
    1
    2
    3
    4
    5
    6
    # 拉取源码
    git clone https://github.com/wg/wrk
    # mbp2018 大概编译10分钟
    cd wrk && make
    # 运行
    wrk -h
Linux

源码安装

1
2
3
4
5
6
# 拉取源码
git clone https://github.com/wg/wrk
# 编译过程相关依赖可以参照 dockerfile 中的依赖项
cd wrk && make
# 运行
wrk -h
Docker安装

Dockerfile内容如下,较少的依赖,编译后无依赖项

1
2
3
4
5
6
7
8
FROM ubuntu:latest as BUILD
WORKDIR root
ADD ./ /root/wrk
RUN cd wrk && apt update && apt install make gcc unzip openssl libterm-readkey-perl -y
RUN make

FROM ubuntu:latest
COPY --from=BUILD /root/wrk/wrk /usr/local/bin

使用介绍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
wrk: invalid option -- h
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 # 全局请求 header
--latency Print latency statistics # 输出延迟统计信息
--timeout <T> Socket/request timeout # 单次请求超时时间
-v, --version Print version details # 版本

Numeric arguments may include a SI unit (1k, 1M, 1G) # 数值参数可以包括单位(1K、1M、1G)
Time arguments may include a time unit (2s, 2m, 2h) # 时间参数可以包括时间单位(2s、2m、2h)

示例

使用 nodejs 写了一个脚本, 用于测试并发

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
const http = require('http');
const port = Number(process.argv[2]) || 0;
console.log(port);

let count = 0;
http.createServer((req, res) => {
if (req.url.includes('status')) return res.end();
if (req.url.includes('count')) { // 可以事后统计实际处理的请求数量
res.write(`hello ${count}`);
return res.end();
}
let closed = false; // 记录请求被取消
req.on('close', () => {
closed = true;
})
setTimeout(() => {
if (closed) {
console.log('req cancel'); // 最终停止时可能有部分请求被强制取消,作为记录
return res.end();
}
res.write(`hello ${port}`);
res.statusCode = 200;
res.end();
count++; // 计数
}, Math.random() * 1000) // 模拟响应处理延迟
}).listen(port, () => {
console.log(`server is running at ${port}`);
});

使用 pm2 进程管理启动集群服务,多进程方式处理响应

动态请求脚本内容如下

1
2
3
4
5
6
7
8
counter = 1

function request()
path = "/" .. counter
wrk.headers["X-Counter"] = counter # 为每次请求头增加叠加数字
counter = counter + 1
return wrk.format(nil, path)
end

请求示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ wrk -c 5 -t 5 -s 1280.lua --latency http://127.0.0.1:1280/

Running 10s test @ http://127.0.0.1:1280/ # 默认执行10s
5 threads and 5 connections # 5个线程,一共5个客户端, 平均一个线程作为一个客户端
Thread Stats Avg Stdev Max +/- Stdev
(平均值) (标准差) (最大值) (正负一个标准差所占比例)
Latency 531.20ms 284.56ms 1.01s 59.34% (延迟)[主要关注]
Req/Sec 2.44 2.57 10.00 91.95% (每秒处理中的请求数)
Latency Distribution (延迟分布)
50% 576.00ms # 50%以内的请求
75% 777.17ms # 75%以内的请求
90% 914.97ms # 90%以内的请求
99% 1.01s # 99%以内的请求
91 requests in 10.02s, 13.95KB read (10s之内共处理完成了91个请求,读取了13.95KB数据)
Requests/sec: 9.09 (平均每秒262.22个请求)
Transfer/sec: 1.39KB (平均每秒读取数据554.27KB)

参考文章

  1. https://www.escapelife.site/posts/4b014d0b.html
  2. https://corvo.myseu.cn/2021/03/24/2021-03-24-使用wrk压测并精细控制并发请求量/
  3. http://www.taodudu.cc/news/show-5177501.html?action=onClick
本文作者 : 萧逸雨
原文链接 : http://qiubo.ink/2023/08/30/学习使用wrk进行压力测试/
版权声明 : 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!