|
wrk 是一种高效的 HTTP 基准测试工具,能够在单个多核 CPU 上运行时产生大量负载。它将多线程设计与 epoll 和 kqueue 等可伸缩事件通知系统相结合。因此,使用 wrk 使用较少的线程即可以压测出非常可观的请求数据。 并且我们可以通过一个可选的 LuaJIT(Lua) 脚本来提供更多的请求参数的定制,参数加密、鉴权请求等。 基础使用
+ k4 y ?: j7 [) C1 f! G/ F使用类 Unix 环境,在 CentOs 或 MacOs 上进行测试 wrk 开源 GitHub 地址: https://github.com/wg/wrk& {6 m& ?0 m& g$ A* V
通过 git clone 的形式下载 源码包,进入目录下,执行 make ,然后开始编译安装,等待一会即可完成。 wrk 使用参数说明
1 y: Z# O/ C1 S, q7 z! L-c, --connections: 总的连接数(每个线程处理的连接数=总连接数/线程数)4 g5 E4 i6 w' h6 n
-d, --duration: 测试的持续时间,如2s(2second),2m(2minute),2h(hour)4 ?: @: H4 l' o7 `. ^2 D# O* T
-t, --threads: 需要执行的线程总数, B! m& X, |0 g# B7 v: D
-s, --script: 执行Lua脚本,这里写lua脚本的路径和名称,后面会给出案例% z6 ~! ?- n& H9 r3 {
-H, --header: 需要添加的头信息,注意header的语法,举例,-H “token: abcdef”,说明一下,token,冒号,空格,abcdefg(不要忘记空格,否则会报错的)。
/ Q. Z5 n! C. O--latency: 显示延迟统计信息' i0 s, h' h6 m
--timeout: 超时的时间: y* ~+ f3 |0 a* `% y( [( P% f- y
例子* I# U, }7 M. w+ \
wrk -t12 -c400 -d30s http://127.0.0.1:8080/index.html
! r' |5 ^; v% v7 `6 s$ c该请求意思为: 使用 wrk 使用12个线程,400个连接,请求 url 30s 压测结束后的结果:
, N& J: ]$ r! i: d0 @2 n( P& jRunning 30s test @ http://127.0.0.1:8080/index.html
" }- L" O& q4 l6 M4 B 12 threads and 400 connections+ I7 Z" _! o/ x. C* D4 w# O
Thread Stats Avg Stdev Max +/- Stdev
: t1 d0 N7 x& c2 ^0 F Latency 635.91us 0.89ms 12.92ms 93.69%6 ~+ l }) x! P4 h; |, ^
Req/Sec 56.20k 8.07k 62.00k 86.54%0 { x& ]' L% K4 G; f2 W
22464657 requests in 30.00s, 17.76GB read
- m+ c2 P) Z aRequests/sec: 748868.531 D& F( W; h# {5 P. Y
Transfer/sec: 606.33MB
4 J6 y6 S% ]+ ]8 h% w9 Q返回结果说明: Latency:响应时间Req/Sec:每个线程每秒钟的执行的连接数
. ~* {5 ^( d2 S" {Avg:平均" R- x, m" }0 H* \ O9 k
Max:最大
: K& ^0 M0 g1 q& c+ p' ?$ @Stdev:标准差+/- Stdev: 正负一个标准差占比8 W s/ y& a: C% \. `
Requests/sec:每秒请求数(也就是QPS),这是一项压力测试的性能指标,通过这个参数可以看出吞吐量7 g* o' @# \& e9 U; r' v" }
Latency Distribution,如果命名中添加了2 }8 n- Y4 L e
latency就会出现相关信息, K1 R; ?3 w1 a7 h" n* ?
实战9 Y' v% h3 h- N L
使用 wrk 对鉴权的接口进行调用压测。由于是鉴权的接口,需要根据密钥和时间戳动态的生成 secret 然后对后端进行请求,才能通过验证。这里我们引入 lua 脚本
. _8 N3 b3 X$ o2 A3 L5 _0 J/ O由于 wrk 工具里面 自带 luaJit ,所以我们不用下载。但是需要 md5 的模块,所以需要使用 luarocks 来管理和下载 lua 模块和包。 安装Luarocks 包管理工具
) N' G9 r5 Y0 b( j& z. e1 t5 H( ~LuaRocks 是 Lua 模块的包管理器。它允许您将 Lua 模块创建并安装为自包含包(称为 rocks )。您可以在 Unix 和 Windows 上下载和安装 LuaRocks。官网:https://luarocks.org/ 通过 curl 下载
6 ]. `4 T$ ^# E0 Kcurl -o luarockt-3.0.3.tar.gz http://luarocks.github.io/luarocks/releases/luarocks-3.0.3.tar.gz
+ i3 `$ r4 @7 q, E w) _解压 luarockt-3.0.3.tar.gz后,进入目录下 指定到 wrk 里 LuaJit 的目录进行 configure //这里指定你自己的 `wrk` 路径% i$ k. u& ?5 S( t: S8 n# i# S
./configure --with-lua=../wrk/obj
- O2 _4 k+ j. c7 ~+ _编译安装
' W, `# T# F- _% \1 f2 G) `make install1 d* ^$ z& n4 a8 z. y: n
通过 Luarocks 安装 md5 模块
7 O+ |. V2 R& x* Vluarocks install md5 开始请求8 J4 C N% C/ W3 e
我们需要像 url http://127.0.0.1:9000 网关进行 POST 请求,该网关会对请求进行鉴权和验证,并判断请求的实效性。所以我们需要在请求时动态改变请求参数,因此需要结合 Lua 脚本。 Lua 脚本 helloDemo.lua7 T6 B) p G9 q5 L, [
md5=require("md5")
8 p0 `! d% x6 W. p-- md5加密,拼接请求对象/ w2 e) a# g, U b2 b
function buildJson(json)0 X: w6 [1 Q% b& g1 z" `
local apiKey = "abcdefg1234567"
- @8 v8 S; ^; g9 I* D: U8 G local password = "qwerxxxx"
1 I8 q2 H/ i3 r& P7 A local timestamp = os.time() .. "000"3 z$ ~; N( p: u7 K7 R2 j/ S
local secret = md5.sumhexa(apiKey .. timestamp .. password)
G& L. \! k, p3 S- L, }' J local body = json .. "×tamp=" .. timestamp .. "&secret=" .. secret
0 o, C& s: F- b. @
. _2 B9 `4 }2 [# }5 |+ T$ f0 m return body
5 Q1 i( E) h0 zend wrk.method = "POST"
, K8 \. v0 v8 Q2 N9 X* E/ pwrk.body = buildJson("serviceName=com.github.dapeng.service.HelloService&version=1.0.0&methodName=sayHello¶meter={\"body\": {\"request\": {\"bizTag\": \"order\", \"step\": 100}}}")( s5 y9 U/ V; U
wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"7 t+ H& w/ V- N
请求脚本 #!/usr/bin/env bash
9 i: ]' G$ A% s) v4 s3 u" xtime1=`date +%s`) b' r' N3 H, Y1 i; N G6 E& I
echo "开始时间 `date +%Y%m%d%H%S`"" G- I+ i" l2 x3 l, E( K
# wrk 安装目录 -s 后指定上面写好的lua脚本
D$ ^ P4 g0 ~; ?( Z~/ideaspace/dapeng/benchmark/wrk/wrk -t4 -c400 --timeout 5s -d 60s -s lua/$1.lua --latency 'http://127.0.0.1:9000/api/e1bfd762321e409cee4ac0b6e841963c'
# H) l9 Y R+ otime2=`date +%s`. k9 p1 n0 p4 b- Y# F
useTime=$[time2 - time1]% o( {5 q4 q, B, T7 v V/ c, Q% X
echo "结束时间 `date +%Y%m%d%H%S`"# B: w$ @1 W c+ H, P+ M- [5 Q
echo "总共花费 $useTime s"
, W" t$ p- ]: \( a1 O/ d执行脚本 sh start-wrk.sh helloDemo/ y. u: Y/ D2 y; T& V
通过上面方式,我们就可以开始请求已鉴权的接口 总结/ z, S5 l8 T M9 F. E$ P3 `9 n
wrk 是一款高性能的 http 请求压测工具,它使用了 Epoll 模型,使所有请求都是异步非阻塞模式的,因此对系统资源能够应用到极致,可以压满 cpu。
8 l# w3 P [7 S; twrk 可以落站使用 Lua 脚本。该特性可以使我们通过 脚本动态的改变请求参数,对请求压测提供的多样性的选择和定制。 后续1 L K6 Q0 D" `( z
1. 去除 CO, m1 o5 U. q- h$ I' B% O2 M1 N
关于 wrk 测试延迟分布不准确的问题,涉及到 Coordinated Omission 的原因,可 Google
7 [, A4 W9 u# e& o F4 F在 src/wrk.c
0 I' z8 L. Q$ Z/ B$ c7 r将下面部分代码注释:
: l6 }& l1 T# ?" y// if(complete / cfg.connections > 0) {
: J" t5 x6 u$ p// int64_t interval = runtime_us / ( complete / cfg.connections);
% K7 K b T: u* i& }// stats_correct(statistics,latency,interval);
4 s' T0 I' P0 {关于 wrk 测试延迟分布不准确的问题,涉及到 Coordinated Omission 的原因,可 Google,也可以参考 wrk2 * W4 G6 Y& ]# C+ d
/ [5 t! B* o- @; ~3 @
wrk入门总结- & W5 Z4 D- \) G0 B7 _' L
. Z. N% l) J! H2 K- 一、功能介绍:
- 二、安装过程:
6 l( v% c$ i [* R i- 1 M d6 ?( h$ r) F9 G: ?; x
# T* z( w0 u0 L5 X# ]8 z
- 三、wrk 初步使用
- - `9 S# Q" B- w7 d: h
- ! b; ^) Q* v- c) U
- 基本用法:
- / r' A( B# v4 w2 i" T! O
2 E* E$ `' B: c" T& y$ R
8 z/ b( g. y2 f% x& p2 }, a) d
- 四 测试场景
1 C0 ^/ j) h3 F
/ B- ~3 j) \& e) t3 X' Y$ O
5 P9 M+ r Z- _# U( a# J
* `( w K$ T, c7 h# ?! W, E 5 I5 R+ N8 }. k
( b( A: r3 M0 K" h/ `
一、功能介绍: wrk2是一个主要基于wrk的HTTP基准测试工具,wrk2经过修改后能够提供稳定的吞吐量负载以及更精确的延时统计,即通过设置参数,wrk2增加了–rate或-R参数设置吞吐量(每秒总请求数)及–u_latency参数显示延时统计。 二、安装过程:wrk安装过程非常简单,下载源码后在项目目录下执行make命令即可。
[! D, i* D1 P8 I
/ Z! b5 G6 p% t8 Y* B& _ 系统无法使用make,make install,一般出现== -bash: make: command not found ==的提示,是因为安装系统的时候使用的是最小化安装,缺少make、vim等常用命令。% z& M6 p% L6 f$ |9 E
直接安装make即可解决问题: [root@XXX wrk2-master]#yum -y install gcc automake autoconf libtool make- l' Q; F4 ~& K+ R+ i
& @. X8 Y1 O* ?+ M) O H, W
安装g++: [root@XXX wrk2-master]#yum install gcc gcc-c++& S0 N2 A* F- Y
- K4 }( }! M# }' P
2. src/wrk.h:11:25: fatal error: openssl/ssl.h: No such file or directory% T6 J5 s: ?+ p, l2 \
https://img-blog.csdnimg.cn/2020052220505566.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NjY2NzeTk5,size_16,color_FFFFFF,t_70+ y; t9 M; Q* G7 R. c
问题在于:系统中缺少openssl库,安装即可 [root@XXX wrk2-master]# yum install openssl-devel 或者[root@XXX wrk2-master]# yum install libssl-dev
8 a& y8 h0 D- F" Z' \9 R2 d3 m O( O3 G. l) O
三、wrk 初步使用 # HTTP连接数,如1k,1M,1G, -d, --duration <T> Duration of test
& I6 C5 s; }7 Z # 测试持续时间,如 2s 2m 2h -t, --threads <N> Number of threads to use " O7 _) N$ H) x1 |( h5 ?
# 开启的线程数 -s, --script <S> Load Lua script file
- G- K$ ^8 u7 a% [6 z' L8 h: S # 进阶功能,使用 lua 脚本 -H, --header <H> Add header to request
+ M \. g2 ]7 E( N # 添加请求头 9 S: q; L5 s8 P- h* s
# 打印详细延迟统计 -L --latency Print latency statistics -U --u_latency Print uncorrceted latency statistics ==
; Q6 T5 D r) A7 p; i' ?) g% j# 设置请求超时时间,大于该时间的请求将被记录== --timeout <T> 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 <T> work rate (throughput)
7 R% |4 l4 `4 N6 `: Y9 ]#工作速率(吞吐量)即每个线程每秒钟完成的请求数 in requests/sec (total) [Required Parameter]
) O3 y6 f0 |- [/ K1 ]
: K+ j- x2 x" y4 a7 n# A; N- {, Y* I- 使用方法–readme) W$ S2 w" H( z5 {3 d) d. Q
[td]| 使用方法 | 说明 | 吞吐量/每秒总请求数 | | 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个请求 | 延迟标识,延迟百分比 | / o% ?1 l+ f E* Y1 u5 S" L* F) b, K
四 测试场景- 测试HTTP协议网络的性能[root@XXX scripts]# wrk -t2 -c1000 -d15 -R1000 --latency https://www.baidu.com/
8 J/ X4 f- J$ {: z* V: sRunning 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 ! V1 U/ ~! c$ A3 W, ^% n( Y- M
压测简单说明:以上使用了2个线程1000个http连接,对baidu进行了15s的压测,并要求在压测结果中输出响应延迟信息。 - 测试当前服务的最大QPS
进入安装目录,运行
, ]- @9 O$ Z% E: t1 _! _ [td]| 通过-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 |
% f" \2 \ W3 A# d8 O, D从以上的测试过程中可以看出,服务最大的每秒请求量为13000,可见性能压测的QPS为1.3万左右,考虑本机测试性能损耗问题,即QPS>1.2万。 - 使用Lua脚本个性化wrk压测; i, c7 r" A! u V4 R
以上是介绍wrk的安装及简单的使用,可以看出wrk的使用较简单方便,且测试结果清晰,一般情况下关注的指标主要是:90分位延迟、99分位延迟及Requests/sec。但是工作上往往需要较复杂的测试场景,这种简单的压测可能就不满足需求。比如,使用POST 方法跟服务器交互;每次请求使用不同的参数;为了更好的模拟服务场景,需要使用wrk的script lua脚本来定制压测过程,即满足定制化的需求。
: _; X2 ` e" r6 L8 F5 J 有关wrk高级使用方法,可以查看我的另一篇博客:wrk2的高级使用方法 |