wrk2是一个主要基于wrk的HTTP基准测试工具,wrk2经过修改后能够提供稳定的吞吐量负载以及更精确的延时统计,即通过设置参数,wrk2增加了–rate或-R参数设置吞吐量(每秒总请求数)及–u_latency参数显示延时统计
wrk安装过程非常简单,下载源码后在项目目录下执行make命令即可
# git clone https://github.com/giltene/wrk2.git 下载源码
# cd wrk2 安装目录
# make
[root@XXX wrk2-master]# make
-bash: make: command not found
Building LuaJIT...
make[1]: Entering directory '/usr/local/wrk2/wrk2/deps/luajit/src'
make[1]: gcc: Command not found
make[1]: gcc: Command not found
make[1]: gcc: Command not found
make[1]: gcc: Command not found
make[1]: gcc: Command not found
make[1]: gcc: Command not found
Makefile:231: *** Unsupported target architecture. Stop.
make[1]: Leaving directory '/usr/local/wrk2/wrk2/deps/luajit/src'
Makefile:61: recipe for target 'deps/luajit/src/libluajit.a' failed
make: *** [deps/luajit/src/libluajit.a] Error 2
src/hdr_histogram.c:15:10: fatal error: zlib.h: No such file or directory
#include
^~~~~~~~
In file included from src/wrk.c:3:0:
src/wrk.h:11:10: fatal error: openssl/ssl.h: No such file or directory
#include
^~~~~~~~~~~~~~~
[root@XXX wrk2-master]# ln -s /export/ccc/wrk2-master/wrk /usr/local/bin
root@apig:/usr# wrk
Usage: wrk
Options:
-c, --connections Connections to keep open
-d, --duration Duration of test
-t, --threads Number of threads to use
-s, --script Load Lua script file
-H, --header Add header to request
-L --latency Print latency statistics
-U --u_latency Print uncorrected latency statistics
--timeout Socket/request timeout
-B, --batch_latency Measure latency of whole
batches of pipelined ops
(as opposed to each op)
-v, --version Print version details
-R, --rate work rate (throughput)
in requests/sec (total)
[Required Parameter]
Basic Usage: wrk
Options:
-c, --connections Connections to keep open # HTTP连接数,如1k,1M,1G,
-d, --duration Duration of test # 测试持续时间,如 2s 2m 2h
-t, --threads Number of threads to use # 开启的线程数
-s, --script Load Lua script file # 进阶功能,使用 lua 脚本
-H, --header Add header to request # 添加请求头
#打印详细延迟统计
-L --latency Print latency statistics
-U --u_latency Print uncorrceted latency statistics
==# 设置请求超时时间,大于该时间的请求将被记录==
--timeout Socket/request timeout
-B, --batch_latency Measure latency of whole
batches of pipelined ops
(as opposed to each op)
-v, --version Print version details
-R, --rate work rate (throughput) #工作速率(吞吐量)即每个线程每秒钟完成的请求数
in requests/sec (total)
[Required Parameter]
使用方法 | 说明 | 吞吐量/每秒总请求数 |
---|---|---|
wrk -t2 -c100 -d30s -R2000 http://127.0.0.1:8080/index.html | 2个线程,100个连接,持续时间30s 每秒2000个请求 | Requests/sec: 2000.12 |
wrk -t2 -c100 -d30s -R2000 --latency url | 2个线程,100个连接,持续时间30s,每秒2000个请求 | 延迟标识,延迟百分比 |
[root@XXX scripts]# wrk -t2 -c1000 -d15 -R1000 --latency https://www.baidu.com/
Running 15s test @ https://www.baidu.com/ ------压测时间15s
2 threads and 1000 connections -------共2个测试线程,1000个连接
Thread calibration: mean lat.: 24.071ms, rate sampling interval: 41ms
Thread calibration: mean lat.: 24.373ms, rate sampling interval: 40ms
Thread Stats Avg Stdev Max +/- Stdev -----平均值 标准差 最大值 正负一个标准差所占的比例
Latency 13.10ms 5.09ms 124.16ms 95.55% -----延迟
Req/Sec 449.03 706.21 5.15k 94.26% -----处理中的请求数
Latency Distribution (HdrHistogram - Recorded Latency) -----延迟分布
50.000% 12.34ms
75.000% 13.68ms
90.000% 15.83ms -----90分位的延迟
99.000% 21.14ms ----99分位的延迟
99.900% 107.97ms
99.990% 124.22ms
99.999% 124.22ms
100.000% 124.22ms
#[Mean = 13.101, StdDeviation = 5.093]
#[Max = 124.160, Total count = 2201]
#[Buckets = 27, SubBuckets = 2048]
13795 requests in 15.00s, 206.31MB read ----15s内共处理完成了13795个请求,读取了206.31MB数据
Requests/sec: 919.62 -----平均每秒处理完成919.62个请求
Transfer/sec: 13.75MB -----平均每秒读取数据13.75MB
压测简单说明:以上使用了2个线程1000个http连接,对baidu进行了15s的压测,并要求在压测结果中输出响应延迟信息。
进入安装目录,运行
通过-R参数获取吞吐量参数 | 每秒请求量的结果 |
---|---|
./wrk2 -t10 -c50 -d30 -R3000 -H “Host:xxx.com” http://localhost/a/a.mp4 -L | Requests/sec: 3000.12 |
./wrk2 -t10 -c50 -d30 -R5000 -H “Host:xxx.com” http://localhost/a/a.mp4 -L | Requests/sec: 5000.12 |
./wrk2 -t10 -c50 -d30 -R10000 -H “Host:xxx.com” http://localhost/a/a.mp4 -L | Requests/sec: 9800.12 |
./wrk2 -t10 -c50 -d30 -R20000 -H “Host:xxx.com” http://localhost/a/a.mp4 -L | Requests/sec: 12500.12 |
./wrk2 -t10 -c50 -d30 -R30000 -H “Host:xxx.com” http://localhost/a/a.mp4 -L | Requests/sec: 13000.12 |
从以上的测试过程中可以看出,服务最大的每秒请求量为13000,可见性能压测的QPS为1.3万左右,考虑本机测试性能损耗问题,即QPS>1.2万。
init = function(args)
request = function()
response = function(status, headers, body)
done = function(summary,latency, requests)
全局变量
wrkwrk = {
scheme = "http",
host = "localhost",
port = nil,
method = "GET",
path = "/",
headers = {},
body = nil
}
wrk功能高级的地方在于使用luajit进行自定义功能扩展,使用自定义函数构造不同的请求场景,常用的函数有:
function setup(thread) 在创建线程时调用,wrk会为每一个测试线程调用一次setup方法,并传入代表测试线程的对象thread作为参数。setup方法中可操作该thread对象,获取信息、存储信息、甚至关闭该线程。
function init(args) 在线程启动时调用一次
function delay() 在每次发送request之前调用
function request() 用来生成请求,每一次请求都会调用该方法,所以不要在这里写入耗时的操作,如果复杂的请求,在init函数就构造好,这里直接引用
function response(status, headers,body) 在每次收到一个响应时调用;为提升性能,如果没有定义该方法,那么wrk不会解析headers和body
function done(summary, latency,requests) 该方法在整个测试过程中只会调用一次,可从参数给定的对象中,获取压测结果,生成定制化的测试报告。
变量wrk是一个table类型的全局变量,若修改改table,则会影响所有的请求。
wrk = {}
function wrk.format(method, path, headers, body)
wrk.format returns a HTTP request string containing the passed parameters merged with values from the wrk table.
– 根据参数和全局变量wrk,生成一个HTTP请求字符串。
function wrk.lookup(host, service)
wrk.lookup returns a table containing all known addresses for the host and service pair. This corresponds to the POSIX getaddrinfo()function.
– 给定host和service(port/well known service name),返回所有可用的服务器地址信息。
function wrk.connect(addr)
wrk.connect returns true if the address can be connected to, otherwise it returns false. The address must be one returned from wrk.lookup().
–测试与给定的服务器地址信息是否可以成功创建连接
一般get请求url中参数固定的情况下,不需要修改脚本文件,如果需要构造特殊的请求则需要创建脚本文件,
counter = 0
num=0
request = function()
path = "/" .. counter .."?arg=" ..num
counter = counter + 1
num = num+1
return wrk.format("", path)
end
执行脚本 wrk -t 2 -c50 -d 15s -R2000 --latency "http://IP:port/uri" --script=http_get.lua
wrk.method = "GET"
wrk.body='{"query": {"multi_match": { "query": "北京 AABBCCDDEEFFF", "fields": [ "address", "address-jdidx" ] }}}'
wrk.headers["Content-Type"] ="application/json"
执行脚本 wrk -t 2 -c50 -d 15s -R2000 --latency "http://IP:port/uri" --script=get_matche.lua
进入到scripts目录下,新建一个lua文件,作为使用post方法的接口文件,修改内容如下:
wrk.method = "POST"
wrk.body='{"KeyId":10}'
wrk.headers["Content-Type"] ="application/json"
执行脚本 wrk -t 2 -c50 -d 15s -R2000 --latency "http://IP:port/uri?key=value" --script=post.lua
测试场景:http连接的url存在文件中,此种情况下,在init阶段将uri读取到wrk table中,requests只需引用即可,可提高性能。比如存在uri.txt /a.txt /b.txt /c.txt /d.txt
创建lua脚本文件,file_uri.lua
–uri.txt /a.txt /b.txt /c.txt /d.txt
urimap={}
counter = 0
function init(args)
for line in io.lines("uri.txt") do
print(line)
urimap[counter] = line
counter=counter+1
end
count =0
end
request = function()
counter = counter +1
path = urimap[counter % table.getn(urimap) +1]
return wrk.format(nil, path)
end
执行脚本 wrk -t 2 -c50 -d 15s -R2000 --latency "http://IP:port/uri" --script=file_uri.lua