1、介绍
官方解释 wrk is a modern HTTP benchmarking tool capable of generating significant load when run on a single multi-core CPU. It combines a multithreaded design with scalable event notification systems such as epoll and kqueue.
它结合了多线程以及类似epoll、kqueue的多事件模式,可以在单机多核CPU的条件下构造大量的负载。
wrk 是一个能够在单个多核 CPU 上产生显著负载的 HTTP 基准测试工具。它采用了多线程设计,能够在单机多核 CPU 的条件下,使用系统自带的高性能 I/O 机制,如 epoll,kqueue 可扩展事件通知机制等,通过多线程和事件模式,对目标机器产生大量的负载。此外,用户可以指定 LuaJIT 脚本来完成 HTTP 请求生成、响应处理和自定义报告等功能。
2、wrk官网
GitHub - wg/wrk: Modern HTTP benchmarking tool
3、优劣
工具优点 劣点wrk
wrk的优势主要有以下几点:
- 轻量级的性能测试工具
- 安装简单(git clone即可)
- 学习简单,稍微看看文档就可以直接上手
- 基于系统自带的高性能I/O机制,利用异步的事件驱动框架,通过很少的线程可以压出跟大的并发量(对于测试宿主机几乎无cpu的压力)
目前支持单机压测,即不支持多机器对目标的压测,即每次压测的机器地址很难去改变,可以改变压测的接口地址,但是压测的机器地址变不了curl loader
curl loader使用的是真正的C编写的客户端协议栈,即基于 libcurl 的 HTTP和FTP协议和 基于 openSSL 的 TLS/SSL,并模拟用户行为,支持登录和身份验证。
4、wrk 安装
git clone https://gitee.com/mirrors/wrk.git
wrk 只能被安装在类 Unix 系统上,所以我们需要一个 Linux 或者 MacOS 环境。Windows 10 安装需要开启自带的 Ubuntu 子系统。
4.1 Linux 安装
4.1.1 Ubuntu/Debian
依次执行如下命令:
sudo apt-get install build-essential libssl-dev git -y
git clone https://github.com/wg/wrk.git wrk
cd wrk
make
# 将可执行文件移动到 /usr/local/bin 位置
sudo cp wrk /usr/local/bin
4.1.2 CentOS / RedHat / Fedora
依次执行如下命令:
sudo yum groupinstall 'Development Tools'
sudo yum install -y openssl-devel git
git clone https://github.com/wg/wrk.git wrk
cd wrk
make
# 将可执行文件移动到 /usr/local/bin 位置
sudo cp wrk /usr/local/bin
5、基础用法
5.1 【基本参数】
-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,lua脚本,使用方法往下看
-H, --header <H> Add header to request,添加http header, 比如. “User-Agent: wrk”
--latency Print latency statistics,显示延迟统计
--timeout, -T: <T> Socket/request timeout,超时的时间
-v, --version Print version details
<N>代表数字参数,支持国际单位 (1k, 1M, 1G)
<T>代表时间参数,支持时间单位 (2s, 2m, 2h)
5.2 测试报告
wrk -c 10000 -t 100 http://127.0.0.1:80/test -d 20s -T2 --latency
Running 20s test @ http://127.0.0.1/test
100 threads and 10000 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 146.36ms 253.95ms 2.00s 88.39%
Req/Sec 1.24k 298.79 3.61k 69.12%
Latency Distribution
50% 34.30ms
75% 176.93ms
90% 459.42ms
99% 1.16s
2484504 requests in 20.10s, 781.90MB read
Socket errors: connect 0, read 0, write 0, timeout 9316
Requests/sec: 123612.53
Transfer/sec: 38.90MB
我们来具体说一说,报告中各项指标都代表什么意思:
Running 30s test @ http://www.baidu.com (压测时间30s)
12 threads and 400 connections (共12个测试线程,400个连接)
(平均值) (标准差) (最大值)(正负一个标准差所占比例)
Thread Stats Avg Stdev Max +/- Stdev
(延迟)
Latency 386.32ms 380.75ms 2.00s 86.66%
(每秒请求数)
Req/Sec 17.06 13.91 252.00 87.89%
Latency Distribution (延迟分布)
50% 218.31ms
75% 520.60ms
90% 955.08ms
99% 1.93s
4922 requests in 30.06s, 73.86MB read (30.06s内处理了4922个请求,耗费流量73.86MB)
Socket errors: connect 0, read 0, write 0, timeout 311 (发生错误数)
Requests/sec: 163.76 (QPS 163.76,即平均每秒处理请求数为163.76)
Transfer/sec: 2.46MB (平均每秒流量2.46MB)
5.3 使用 Lua 脚本进行复杂测试
wrk默认是采用GET请求方式进行接口测试,如果需要使用POST请求就需要使用到lua脚本,通过加载编写好的lua脚本来进行定制化的请求。采用
-s 或者 --script
可以加载脚本文件。
1. 编写lua脚本,填写post的数据, 如 post.lua
单纯的利用POST提交方法
wrk.method = "POST"
wrk.body = "name=zhangsan&password=123456"
wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"
或者可以采用以下的方式:
wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"
request = function()
method = "POST"
body = "name=zhangsan&password=123456"
path = "/user/login" return wrk.format(method,path,nil,body)
end
自定义请求和参数
要求每一次的参数不同如何处理
request = function()
uid = math.random(1,1000000)
path = "/login?uid"..uid return wrk.formate(nil,path,nil,nil)
end
设置延迟
function
delay()
return 10 -- 表示设置10ms的延迟 end
先登录后请求
这个地方是为了对一些需要先登录获取token,后续的请求都需要携带token请求的接口进行测试的,参照官方给出的lua脚本案例:auth.lua
-- example script that demonstrates response handling and
-- retrieving an authentication token to set on all future
-- requests
token = nil
path = "/authenticate" -- 初始的请求url
request = function()
return wrk.format("GET", path) -- 发送第一次authenticate认证请求
end
response = function(status, headers, body)
if not token and status == 200 then
token = headers["X-Token"]
path = "/resource" -- 拿到之后做修改
wrk.headers["X-Token"] = token -- 修改头,携带token进入后续的请求
end
end
pipeline请求
即一次发送多个请求,参照官方给出的pipeline.lua
-- example script demonstrating HTTP pipelining
init = function(args)
local r = {}
r[1] = wrk.format(nil, "/?foo")
r[2] = wrk.format(nil, "/?bar")
r[3] = wrk.format(nil, "/?baz")
req = table.concat(r)
end
request = function()
return req
end
2. 执行wrk,开始压力测试
wrk -t 32 -c 400 -d 10s --timeout 1s -s post.lua http://10.132.237.12:10521/single_p
版权归原作者 Kingairy 所有, 如有侵权,请联系我们删除。