官方解释 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 请求生成、响应处理和自定义报告等功能。
GitHub - wg/wrk: Modern HTTP benchmarking tool
| 工具 | 优点 | 劣点 |
| wrk | wrk的优势主要有以下几点:
| 目前支持单机压测,即不支持多机器对目标的压测,即每次压测的机器地址很难去改变,可以改变压测的接口地址,但是压测的机器地址变不了 |
| curl loader | curl loader使用的是真正的C编写的客户端协议栈,即基于 libcurl 的 HTTP和FTP协议和 基于 openSSL 的 TLS/SSL,并模拟用户行为,支持登录和身份验证。 |
git clone https://gitee.com/mirrors/wrk.git
wrk 只能被安装在类 Unix 系统上,所以我们需要一个 Linux 或者 MacOS 环境。Windows 10 安装需要开启自带的 Ubuntu 子系统。
依次执行如下命令:
- 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
依次执行如下命令:
- 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
- -c, --connections
Connections to keep open,需要模拟的连接数 - -d, --duration
Duration of test,测试的持续时间 - -t, --threads
Number of threads to use,需要模拟的线程数 -
- -s, --script
Load Lua script file,lua脚本,使用方法往下看 - -H, --header
Add header to request,添加http header, 比如. “User-Agent: wrk” - --latency Print latency statistics,显示延迟统计
- --timeout, -T:
Socket/request timeout,超时的时间 - -v, --version Print version details
-
代表数字参数,支持国际单位 (1k, 1M, 1G) 代表时间参数,支持时间单位 (2s, 2m, 2h)
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)
wrk默认是采用GET请求方式进行接口测试,如果需要使用POST请求就需要使用到lua脚本,通过加载编写好的lua脚本来进行定制化的请求。采用-s 或者 --script可以加载脚本文件。
- 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.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
wrk -t 32 -c 400 -d 10s --timeout 1s -s post.lua http://10.132.237.12:10521/single_p