易陆发现互联网技术论坛

 找回密码
 开始注册
查看: 3360|回复: 2
收起左侧

高性能 Http 压测工具 wrk 的使用,wrk2入门-http性能压测工具总结

[复制链接]
发表于 2020-11-11 17:00:13 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?开始注册

x

wrk 是一种高效的 HTTP 基准测试工具,能够在单个多核 CPU 上运行时产生大量负载。它将多线程设计与 epoll 和 kqueue 等可伸缩事件通知系统相结合。因此,使用 wrk 使用较少的线程即可以压测出非常可观的请求数据。

并且我们可以通过一个可选的 LuaJIT(Lua) 脚本来提供更多的请求参数的定制,参数加密、鉴权请求等。

基础使用
6 t. o/ s  g$ K; l使用类 Unix 环境,在 CentOs 或 MacOs 上进行测试

wrk 开源 GitHub 地址: https://github.com/wg/wrk
! ^/ C3 U/ _' F% m" s; f0 {通过 git clone 的形式下载 源码包,进入目录下,执行 make ,然后开始编译安装,等待一会即可完成。

wrk 使用参数说明
4 c- w3 T2 c$ b+ b-c, --connections:  总的连接数(每个线程处理的连接数=总连接数/线程数)& r% Y4 ]7 {' N7 g* ]( _' V
-d, --duration:        测试的持续时间,如2s(2second),2m(2minute),2h(hour)
- i  Q" ]( }9 v$ o8 ^5 Y; z. _-t, --threads:         需要执行的线程总数
! q0 f* z) E# r( p$ Q0 p-s, --script:          执行Lua脚本,这里写lua脚本的路径和名称,后面会给出案例
( n' q6 ~8 E% t, G3 f-H, --header:      需要添加的头信息,注意header的语法,举例,-H “token: abcdef”,说明一下,token,冒号,空格,abcdefg(不要忘记空格,否则会报错的)。
2 |; I. @- _3 n+ x  Y' K--latency:     显示延迟统计信息2 J' D# W& k* @, y6 R1 S' \+ E
--timeout:     超时的时间1 o0 S& s+ g/ i
例子
" T6 H5 C/ B; i' c! Dwrk -t12 -c400 -d30s http://127.0.0.1:8080/index.html7 z7 M# P' _) c5 i
该请求意思为: 使用 wrk 使用12个线程,400个连接,请求 url 30s

压测结束后的结果:
" p% `+ ]7 Z( B- X- I& FRunning 30s test @ http://127.0.0.1:8080/index.html
* O- V0 }" e8 k/ q, c4 y8 D  12 threads and 400 connections
6 }! c1 d5 s7 v( V0 X  Thread Stats   Avg      Stdev     Max   +/- Stdev/ k- M& b8 N7 w& {" @
    Latency   635.91us    0.89ms  12.92ms   93.69%9 |3 `: n4 }0 n+ p4 l: ^1 ]. F; N, Q
    Req/Sec    56.20k     8.07k   62.00k    86.54%
8 R/ g3 {2 ?. q: j( P' r  22464657 requests in 30.00s, 17.76GB read5 s. V" K6 y& c3 v
Requests/sec: 748868.53
) \, x/ B$ q3 Y3 K; t5 P( W" dTransfer/sec:    606.33MB
: h' O7 y. c0 s返回结果说明:

Latency:响应时间Req/Sec:每个线程每秒钟的执行的连接数6 q7 L  b7 P% q% g" Y
Avg:平均/ W+ d& d/ F% @
Max:最大
2 k$ v  U* |2 l' w5 _+ O% kStdev:标准差+/- Stdev: 正负一个标准差占比; e4 u, M7 ]# M( M: }4 P) d) s4 K
Requests/sec:每秒请求数(也就是QPS),这是一项压力测试的性能指标,通过这个参数可以看出吞吐量
# s& G5 g5 M# s3 ^4 u2 JLatency Distribution,如果命名中添加了
# \+ r9 Y8 }: {& ^! I$ wlatency就会出现相关信息; ^6 q+ Z2 y  j; d+ |0 }
实战. n; Z2 V/ [3 [0 g) S
使用 wrk 对鉴权的接口进行调用压测。由于是鉴权的接口,需要根据密钥和时间戳动态的生成 secret 然后对后端进行请求,才能通过验证。这里我们引入 lua 脚本9 W( [4 N  c0 C6 Z; i* o( N. e
由于 wrk 工具里面 自带 luaJit ,所以我们不用下载。但是需要 md5 的模块,所以需要使用 luarocks 来管理和下载 lua 模块和包。

安装Luarocks 包管理工具" T. H3 [( r$ x7 @# D
LuaRocks 是 Lua 模块的包管理器。它允许您将 Lua 模块创建并安装为自包含包(称为 rocks )。您可以在 Unix 和 Windows 上下载和安装 LuaRocks。官网:https://luarocks.org/

通过 curl 下载; T# g8 x: Q) h9 R
curl -o luarockt-3.0.3.tar.gz http://luarocks.github.io/luarocks/releases/luarocks-3.0.3.tar.gz" ]  S: E4 H0 v" S
解压 luarockt-3.0.3.tar.gz后,进入目录下 指定到 wrk 里 LuaJit 的目录进行 configure

//这里指定你自己的 `wrk` 路径
' y! D+ }+ T2 z9 z$ A" G/ s./configure --with-lua=../wrk/obj! d" j! T5 g! t: ]% r
编译安装) R) C$ K4 @9 }1 K+ J0 k0 A" l8 _
make install
( M/ H8 y$ f( v通过 Luarocks 安装 md5 模块8 C- ?. |* ?: v8 Q
luarocks install md5

开始请求
* E7 @* r8 M/ i- t# F: j我们需要像 url http://127.0.0.1:9000 网关进行 POST 请求,该网关会对请求进行鉴权和验证,并判断请求的实效性。所以我们需要在请求时动态改变请求参数,因此需要结合 Lua 脚本。

Lua 脚本 helloDemo.lua. F4 {& a& `2 u, c# \
md5=require("md5")
( |7 e/ `: e) d1 e2 Q# T9 N-- md5加密,拼接请求对象
6 `& K8 c( y: X9 w# |1 gfunction buildJson(json)& c6 I. m$ a% i
  local apiKey = "abcdefg1234567"$ O' Z" S& @9 v9 v6 t7 U  w
  local password = "qwerxxxx"
: Y1 s) J4 v% j$ b: w* |  D) ~  local timestamp = os.time() .. "000"
, t7 t! T6 ~, j& D8 l* `' ~* M  local secret = md5.sumhexa(apiKey .. timestamp ..  password)
6 b1 g/ H) K  k4 ?  E. b! Y  local body = json .. "×tamp=" .. timestamp .. "&secret=" .. secret# J9 X4 M, j7 Z4 z3 ~, u2 _/ R' ^
  
1 m- ]9 {0 M* D: U- ~9 p: P  return body
5 I6 Z6 T$ G" i, aend

wrk.method = "POST". E- M0 B: C: V' P
wrk.body = buildJson("serviceName=com.github.dapeng.service.HelloService&version=1.0.0&methodName=sayHello¶meter={\"body\": {\"request\": {\"bizTag\": \"order\", \"step\": 100}}}")9 u1 e. a5 S% n  V# Z  ^
wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"
1 W' K! M$ P2 P  ]! b- X+ M" c( z" J请求脚本

#!/usr/bin/env bash3 F8 T6 j2 b5 c5 h# X0 r% k2 `5 F0 S
time1=`date +%s`9 Z$ P4 H- J1 b( |) ~) S
echo "开始时间 `date +%Y%m%d%H%S`"
5 l2 t8 F; ^% S* D# l# wrk 安装目录 -s 后指定上面写好的lua脚本
6 }, [/ [3 v$ X. 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'
( q& L. T* w3 t+ [# J4 ]time2=`date +%s`" r: ]5 O9 d7 R. D7 |, W
useTime=$[time2 - time1]
3 W" a  E4 e0 {- k" a* Necho "结束时间 `date +%Y%m%d%H%S`"
: i  O! p$ p% `! b" ~echo "总共花费 $useTime s"3 L+ l0 O# @6 h) ]. }# O& r# Z
执行脚本

sh start-wrk.sh helloDemo" j6 v0 P. U2 C& r. {$ R& R4 U2 x
通过上面方式,我们就可以开始请求已鉴权的接口

总结
$ {* C) W5 a& D  f1 Gwrk 是一款高性能的 http 请求压测工具,它使用了 Epoll 模型,使所有请求都是异步非阻塞模式的,因此对系统资源能够应用到极致,可以压满 cpu。
- o' `' n  S4 t5 o% u: kwrk 可以落站使用 Lua 脚本。该特性可以使我们通过 脚本动态的改变请求参数,对请求压测提供的多样性的选择和定制。

后续
6 _& ~8 r+ S5 D9 r/ ~1. 去除 CO1 D9 V' C: ^: U( P$ D
关于 wrk 测试延迟分布不准确的问题,涉及到 Coordinated Omission 的原因,可 Google
4 f6 c9 E# V! w2 t4 Z& i" u在 src/wrk.c
9 |  P. Z, u  Y' x7 j4 c8 X5 F将下面部分代码注释:
4 {' o# c/ Y" k0 V% Z2 f3 z" C//  if(complete / cfg.connections > 0) {
' g# ?  f0 G; N5 z//       int64_t interval = runtime_us / ( complete / cfg.connections);
2 Z& w7 w) q. |$ k# a; ^$ l# U+ [8 t//       stats_correct(statistics,latency,interval);
" X9 c3 T. G' V# P( m3 t关于 wrk 测试延迟分布不准确的问题,涉及到 Coordinated Omission 的原因,可 Google,也可以参考 wrk2


# b+ _, ?" m" \) v
5 q( G- ?* T. Z# a% {& r[color=rgba(0, 0, 0, 0.75)]wrk入门总结4 E: g% Q" U* E! |% z

. ^' |  t3 \: b% r, f7 k9 q4 S0 m  ~一、功能介绍:

  wrk2是一个主要基于wrk的HTTP基准测试工具,wrk2经过修改后能够提供稳定的吞吐量负载以及更精确的延时统计,即通过设置参数,wrk2增加了–rate或-R参数设置吞吐量(每秒总请求数)及–u_latency参数显示延时统计。

二、安装过程:

wrk安装过程非常简单,下载源码后在项目目录下执行make命令即可。

9 Q& ~. h- A2 \& O0 {3 q
  • make编译过程中问题解决:

    1. -bash: make: command not found

    [root@XXX wrk2-master]# make-bash: make: command not found
    0 U! Z6 ^9 @5 u0 a& O/ r9 x, N' c# c
' t1 n( a2 I* N: m

  系统无法使用make,make install,一般出现== -bash: make: command not found ==的提示,是因为安装系统的时候使用的是最小化安装,缺少make、vim等常用命令。
. A/ z: i7 i8 i2 F  直接安装make即可解决问题:

[root@XXX wrk2-master]#yum -y install gcc automake autoconf libtool make
+ c: I0 f/ _" m! }+ q$ y; F0 B) ]  k* o

  安装g++:

[root@XXX wrk2-master]#yum install gcc gcc-c++
# h% V* h' t, c7 ~
1 x$ u+ ]- V& _* J0 G0 _

2. src/wrk.h:11:25: fatal error: openssl/ssl.h: No such file or directory
( t. ~$ C8 N' Dhttps://img-blog.csdnimg.cn/2020052220505566.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NjY2NzeTk5,size_16,color_FFFFFF,t_70# H8 _3 w# X9 e% @
  问题在于:系统中缺少openssl库,安装即可

[root@XXX wrk2-master]# yum install openssl-devel  或者[root@XXX wrk2-master]# yum install libssl-dev* [  _# d+ _" N. k; j! w

9 e5 c) B; g) O7 M: @三、wrk 初步使用
  • 基本用法:

    Basic Usage: wrk <options> <url>

    Options:                                                -c, --connections <N>  Connections to keep open
    $ I* Y  a& X7 g
     # HTTP连接数,如1k,1M,1G,    -d, --duration  <T>  Duration of test  
9 I6 J$ B! }- A* [  y" q    # 测试持续时间,如 2s 2m 2h              -t, --threads <N>  Number of threads to use  
, v" o) k% T$ a6 L8 v( {    # 开启的线程数                                                           -s, --script   <S>  Load Lua script file
$ G) Y2 K$ o: e( F7 P4 X  # 进阶功能,使用 lua 脚本    -H, --header   <H>  Add header to request  
" A. P  Q9 Q; n- ?0 {7 {  # 添加请求头                    
3 B4 Z- u7 [2 p$ Y, o- j # 打印详细延迟统计    -L  --latency    Print latency statistics       -U  --u_latency  Print uncorrceted latency statistics                     ==' ]# ^) @2 J! ^7 t8 I6 g
# 设置请求超时时间,大于该时间的请求将被记录==          --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)   
9 N3 q9 y& Q; v8 f7 e& V#工作速率(吞吐量)即每个线程每秒钟完成的请求数                           in requests/sec (total)                               [Required Parameter]' B% z: n2 |; Y. e! E1 M: O

" l2 A/ @* l0 b
  • 使用方法–readme
    2 C! C3 S. l) K; N
[color=rgba(0, 0, 0, 0.75)][td]
使用方法说明吞吐量/每秒总请求数
wrk -t2 -c100 -d30s -R2000 http://127.0.0.1:8080/index.html2个线程,100个连接,持续时间30s 每秒2000个请求Requests/sec: 2000.12
wrk -t2 -c100 -d30s -R2000 --latency url2个线程,100个连接,持续时间30s,每秒2000个请求延迟标识,延迟百分比

! v1 m4 O& T1 X# h$ c! g! m四 测试场景
  • 测试HTTP协议网络的性能[root@XXX scripts]# wrk -t2 -c1000 -d15 -R1000 --latency https://www.baidu.com/3 n5 x" Y' p, p8 `
    • 19 K7 A4 |8 ]9 z& g/ R/ I
    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

) x1 [. R. O2 k

  压测简单说明:以上使用了2个线程1000个http连接,对baidu进行了15s的压测,并要求在压测结果中输出响应延迟信息。

  • 测试当前服务的最大QPS

      进入安装目录,运行

    - v* i9 k( o; U8 l
[color=rgba(0, 0, 0, 0.75)][td]
通过-R参数获取吞吐量参数每秒请求量的结果
./wrk2 -t10 -c50 -d30 -R3000 -H “Host:xxx.com” http://localhost/a/a.mp4 -LRequests/sec: 3000.12
./wrk2 -t10 -c50 -d30 -R5000 -H “Host:xxx.com” http://localhost/a/a.mp4 -LRequests/sec: 5000.12
./wrk2 -t10 -c50 -d30 -R10000 -H “Host:xxx.com” http://localhost/a/a.mp4 -LRequests/sec: 9800.12
./wrk2 -t10 -c50 -d30 -R20000 -H “Host:xxx.com” http://localhost/a/a.mp4 -LRequests/sec: 12500.12
./wrk2 -t10 -c50 -d30 -R30000 -H “Host:xxx.com” http://localhost/a/a.mp4 -LRequests/sec: 13000.12
6 M* u1 q) C7 [3 Z% T# G6 a1 p6 U

从以上的测试过程中可以看出,服务最大的每秒请求量为13000,可见性能压测的QPS为1.3万左右,考虑本机测试性能损耗问题,即QPS>1.2万

  • 使用Lua脚本个性化wrk压测
    9 ]; A' S* ~6 N1 [+ t  k+ _

  以上是介绍wrk的安装及简单的使用,可以看出wrk的使用较简单方便,且测试结果清晰,一般情况下关注的指标主要是:90分位延迟、99分位延迟及Requests/sec。但是工作上往往需要较复杂的测试场景,这种简单的压测可能就不满足需求。比如,使用POST 方法跟服务器交互;每次请求使用不同的参数;为了更好的模拟服务场景,需要使用wrk的script lua脚本来定制压测过程,即满足定制化的需求。
9 `& Z- o9 u1 x4 w0 R! B  有关wrk高级使用方法,可以查看我的另一篇博客:wrk2的高级使用方法

 楼主| 发表于 2020-11-11 17:00:14 | 显示全部楼层
软件简介, w3 @* H4 Z2 m5 r$ d( l9 d
wrk 是一个比较先进的 HTTP 压力测试工具,当在单个多核 CPU 上运行时,能够产生大量负载。它结合了多线程设计和可扩展的事件通知系统,例如 epoll 和 kqueue。7 e; d% |0 w9 S& m
8 D* V* R+ f( c/ G# E3 x5 [
可选的 LuaJIT 脚本可以执行 HTTP 请求生成,响应处理和自定义报告。! X( `7 D, U" _9 B  Z% t

, g  S/ [3 C5 R$ h4 T0 H  l测试方法:
, a# C- Y0 R5 T* s+ T3 y3 c8 r  H; l; S. ~
wrk -t8 -c400 -r10m http://localhost:8080/index.html
$ c- J/ @) T& a: a8 l输出结果:  X; j( g8 ^- s9 s

6 }: n4 c: z9 }/ ~9 x; J  Making 10000000 requests to http://localhost:8080/index.html! q6 Z" ~# j+ i  C. P# a/ z$ I
    8 threads and 400 connections4 O6 u# N. f" z% r9 T
    Thread Stats   Avg      Stdev     Max   +/- Stdev# t) a. u2 U0 i" }$ e$ `& I
      Latency   439.75us  350.49us   7.60ms   92.88%( N( p" K9 Z& [# c# f
      Req/Sec    61.13k     8.26k   72.00k    87.54%. u( Q& N& S" z2 k
    10000088 requests in 19.87s, 3.42GB read9 N4 k) ?% D  w" e, q# \) c, b/ M
  Requests/sec: 503396.235 c$ t9 s" Y. N+ _' U" M& l4 a; d
  Transfer/sec:    176.16MB& U% u* Y9 q- e* W/ I2 a
 楼主| 发表于 2020-11-11 17:00:15 | 显示全部楼层
一、简介
0 {: b) d* }1 E9 k! p. H7 u. l
8 ^& R1 S1 Z; V% ^. Y  wrk 是一款针对 Http 协议的基准测试工具,它能够在单机多核 CPU 的条件下,使用系统自带的高性能 I/O 机制,如 epoll,kqueue 等,通过多线程和事件模式,对目标机器产生大量的负载。
/ J' |9 w$ ]' a* I( D  C
! d% a7 F, K, Q( d2 `5 E! bwrk是开源的, 代码在 github 上:https://github.com/wg/wrk
; M3 x% _1 y6 }7 q& a6 S' y! b( ^- j6 j' _% R8 l
安装:https://www.cnblogs.com/savorboard/p/wrk.html) u% v# M( z: s: Q4 j' a* n
1 O) o: g% I& n$ j- p# j6 N
; t) X( Z! m  y# X2 E4 v" u
" J# t( w) s* G+ Z
优势:
, `  e* s# [- `" k1 S" w5 }7 ?* E5 ]$ M, B
轻量级性能测试工具6 n, y4 h, e5 P2 s* \- N
安装简单0 a: D: n% S% p* \3 ~& Y
学习曲线基本为0,几分钟就学会使用了6 V: \6 g. L2 M8 n3 H
基于系统自带的高性能I/O机制,如epoll,kqueue,利用异步的事件驱动框架,通过很少的线程就可以压出很大的并发量,例如几万、几十万,这是很多性能测试工具无法做到的。
3 D$ O- V) R! H& _5 |9 y劣势:
$ u+ Q  X" D: X. Y1 U
' {1 U! q6 f6 f: {9 \wrk 目前仅支持单机压测,后续也不太可能支持多机器对目标机压测,因为它本身的定位,并不是用来取代 JMeter, LoadRunner 等专业的测试工具。
. O; t& J  l8 x* a* E+ ?  m
1 Z+ v) g$ y' K2 z, w% \
! f$ E: J# E7 Y) O: r9 S3 s 二、格式及用法
5 X+ `' v4 S3 J* ~1 t6 Z8 ]$ E! w7 W; V- {; H; Z
复制代码
" n4 j1 o1 M, H& i9 z% ^Usage: wrk <options> <url>                           
# }% U& D1 t, R0 o4 D4 D8 l- P5 `6 V& c, A1 k" u
  Options:                                           ' O6 W. H& V2 M" c
    -c, --connections <N>  Connections to keep open  9 u4 W$ |4 s& R  v8 T& b
    -d, --duration    <T>  Duration of test          5 H9 ^% Y6 R3 i6 G/ W
    -t, --threads     <N>  Number of threads to use  
* w$ F% T* w+ Z2 z                                                     
/ B! c$ j3 O& w: s- h7 V- p" q! C    -s, --script      <S>  Load Lua script file      
* p1 d8 F0 ]& z/ l    -H, --header      <H>  Add header to request     / L* W0 D, r% p1 [, _3 j
        --latency          Print latency statistics  
6 \3 b: M/ i* ?: o        --timeout     <T>  Socket/request timeout    5 q! g. [* {, k' U  Y- N$ q
    -v, --version          Print version details     : D2 X( W  |  s# a6 f' ?4 C4 \/ w
                                                
0 H4 r& o2 d8 H6 J! E$ J  Numeric arguments may include a SI unit (1k, 1M, 1G)
2 W  ?; m* F+ q6 e* ^0 C- Y8 B  Time arguments may include a time unit (2s, 2m, 2h)2 }3 y4 A) _; f! w7 V
复制代码
* x" S6 C# O! M8 w8 {& A : O8 D: J) f9 d

6 w% L$ _$ {! Y0 @翻译成中文:# ?; a8 |5 D$ S! q
5 J  ]3 F) t! F5 O" b' u
复制代码
! z" }" ~5 K# z5 b  B' D* h使用方法: wrk <选项> <被测HTTP服务的URL>                           
( v- P+ H. z! R, x
( }, }3 L- f+ a& T5 L$ \  Options:                                           3 T8 L3 @' N* N# s
    -c, --connections <N>  跟服务器建立并保持的TCP连接数量
9 s6 T7 J9 N0 ^* R9 g1 W! o4 p    -d, --duration    <T>  压测时间          3 [5 o7 n4 N: B6 f2 m
    -t, --threads     <N>  使用多少个线程进行压测,压测时,是有一个主线程来控制我们设置的n个子线程间调度  ( A: O8 p/ f8 Y( [& T. D( P
                                                   
$ J  l; k$ `6 n: y    -s, --script      <S>  指定Lua脚本路径      4 F  l* ~7 x. X+ L
    -H, --header      <H>  为每一个HTTP请求添加HTTP头       h+ E& A* O* v/ o% i- d
        --latency          在压测结束后,打印延迟统计信息  ' ^, D2 M+ Q. S3 \6 I& T+ s* R' Z
        --timeout     <T>  超时时间    ( V4 j' b6 [/ j& M
    -v, --version          打印正在使用的wrk的详细版本信                                             
$ h6 o) ?; A4 C* i8 g4 d4 R6 h5 J* D" @4 M
  <N>代表数字参数,支持国际单位 (1k, 1M, 1G)  b: {6 D, }( \+ D' H" Y3 g
  <T>代表时间参数,支持时间单位 (2s, 2m, 2h)
. |  Y9 k9 n5 t/ E2 V复制代码
! i; B1 Q3 a( j. q8 @; m; E
9 u7 ]% k6 h9 N4 {' |) b, j1 S4 _; A5 b, a. }6 {

$ d# t9 A3 G1 y7 z* Q! |
( j5 r" c: j  T2 g7 o) J三、简单压测及结果分析
& v% @+ `/ m2 z# |
- Z6 {8 g0 n2 \: m5 W; y. s做一个简单的压测,分析下结果:
8 ]6 g# H% U( s0 a2 N
3 G7 M/ U/ A1 u  U  u5 \5 }& Mwrk -t8 -c200 -d30s --latency  http://www.bing.com
$ u; G- x. A* ]7 A1 L: [+ ?# L2 } / M% V: j7 H7 ?" ^; x2 [! V' l! l
% f+ x' C# ]8 ?( h8 t- N6 P; n
输出:
7 B$ ^2 d6 F/ A  \4 \' z4 V3 ?$ s/ {& e0 {# N
复制代码
# Q/ o, n3 Q, b  CRunning 30s test @ http://www.bing.com5 }, U! W/ I$ c5 s0 @

) c5 A/ o2 y! P/ J, [% X! i  X% [  8 threads and 200 connections
1 P3 `7 j9 @2 d  A$ Z) w
6 V6 a" Y1 T7 n/ R& J  Thread Stats   Avg      Stdev     Max   +/- Stdev% K8 Y& D4 i4 }) Q0 M0 h% ]# |# i
    Latency    46.67ms  215.38ms   1.67s    95.59%
( U/ g9 H) F3 d/ n$ C5 p    Req/Sec     7.91k     1.15k   10.26k    70.77%3 K. j3 H) z, H0 s+ u
. t3 {) O7 o- L; r
  Latency Distribution  o5 U+ K+ u: k+ Q- i2 ?$ m
     50%    2.93ms  z. ?) ]2 o$ x- i3 T! F4 a- I+ L
     75%    3.78ms* ^; X- f6 R1 G4 i/ l! m, L+ }0 [* N; l
     90%    4.73ms
* U# ?) L$ Y' d5 [     99%    1.35s
% @1 O5 G. ?3 {9 w7 q  |. \( p4 f  1790465 requests in 30.01s, 684.08MB read
& R3 B1 z' {4 y  D0 c/ G# ORequests/sec:  59658.29
7 K6 I9 N4 m$ b" p9 S( F5 K7 PTransfer/sec:     22.79MB& A0 f# ^, l! M. H, P
复制代码5 s! L: n3 h. P1 w  l! d; C8 u
以上是使用8个线程200个连接,对bing首页进行了30秒的压测,并要求在压测结果中输出响应延迟信息。- k+ U1 N0 ~8 z) V8 F
' t0 C9 ]/ x+ H' u7 e9 j
以下是解释压测结果:8 r* `: `1 r) p& t! T$ a
6 }. C; S+ @% M, s' c+ H4 f
复制代码& Q# v) g. }, O" Q, p$ l
Running 30s test @ http://www.bing.com (压测时间30s)! E. |1 [8 P% H( d) t. g

% A' C5 N% u% V3 l5 }+ d7 F' R7 r  8 threads and 200 connections (共8个测试线程,200个连接)
$ c+ K' A5 z5 r$ I( b7 X5 L/ U' z- ?. x' B
  Thread Stats   Avg      Stdev     Max   +/- Stdev
  l5 g5 |' \. M. D) A. [              (平均值) (标准差)(最大值)(正负一个标准差所占比例)
# U3 U/ z% _) w/ h7 A    Latency    46.67ms  215.38ms   1.67s    95.59%) y2 e5 e1 x9 T6 M$ V
    (延迟)/ b) F% w5 v5 {
    Req/Sec     7.91k     1.15k   10.26k    70.77%
9 y) T# K& w0 f+ L/ s- Y    (处理中的请求数)
& _/ W! z  T$ h3 e: e' o6 M- y4 [5 r3 u8 l: ]3 A+ I; w$ w4 C
  Latency Distribution (延迟分布). u. n: w+ Q% x3 d
     50%    2.93ms
  `0 V7 \1 k; i# g" H     75%    3.78ms3 N/ D( @. J, N0 G$ ?
     90%    4.73ms  V8 d  [+ S  A9 @' F" J4 E
     99%    1.35s (99分位的延迟:%99的请求在1.35s以内): Q8 j  Z, q  A8 @. ^* z* b8 A
  1790465 requests in 30.01s, 684.08MB read (30.01秒内共处理完成了1790465个请求,读取了684.08MB数据)/ [1 ]0 I2 b5 a9 Q' }
Requests/sec:  59658.29 (平均每秒处理完成59658.29个请求)
: B  d% w+ F6 A% BTransfer/sec:     22.79MB (平均每秒读取数据22.79MB)" `- \5 u- d3 Y1 ]7 j( B6 A
复制代码6 p  ?: S& o6 g1 n4 |! x

/ Q$ \9 @. K/ g8 M/ |$ l  P, _% e  @
4 e4 E7 z( ~9 w
5 v2 E+ r! P9 }$ o! s" ~4 Z1 W6 Z5 ?- _' ]# ~$ a
四、使用lua脚本进行压测
; ]" h, P! w3 g; O: I8 z( A
- o! Y% \( Z. {) `) r  lua脚本是一种轻量小巧的脚本语言,用标准c语言编写,并以源代码形式开放,其设计目的是为了嵌入应用程序中,从而为程序提供灵活的扩展和定制功能。wrk工具嵌入了lua脚本语言,因此,在自定义压测场景时,可在wrk目录下使用lua定制压测场景。8 e; ^" q) F: q  U9 L
  @6 q1 Z/ p: `0 K9 Z! e
  1、lua声明周期+ _" H! q& @, |. d# ~- |
3 N% ^: U% ^& B' W4 t
    共有三个阶段,启动阶段,运行阶段,结束阶段。wrk支持在这三个阶段对压测进行个性化。   $ G9 g0 y4 ~' B5 N

+ e- b4 h% M3 V0 ~1 L# b( r2 f启动阶段
7 A4 @4 U# d7 F" K1 rfunction setup(thread)4 Q) x) v$ |! X2 O/ }) h
; O& l, E- h  A9 w. w& q; @# }
2 B( V1 J' l: C! }9 r
在脚本文件中实现setup方法,wrk就会在测试线程已经初始化但还没有启动的时候调用该方法。wrk会为每一个测试线程调用一次setup方法,并传入代表测试线程的对象thread作为参数。setup方法中可操作该thread对象,获取信息、存储信息、甚至关闭该线程。0 \( t: z& p' z" Y

. H# v3 d+ y7 W/ S2 ?' w: X7 Gthread.addr - get or set the thread's server address' n4 N9 J4 @( B3 h
thread:get(name) - get the value of a global in the thread's env
' B" C* k) C3 \. Q2 y, Gthread:set(name, value) - set the value of a global in the thread's env3 e9 x8 B4 _% r: v; J1 X3 O
thread:stop() - stop the thread0 a. l/ A/ N' q! G

, D* y( W/ G6 D" M3 M( N$ Z% U# u- u# Y; i. B
运行阶段
, d& R  H& A* tfunction init(args)  --由测试线程调用,只会在进入运行阶段时,调用一次。支持从启动wrk的命令中,获取命令行参数;
( ^* e# I# h: d1 D$ [  h) c' ~function delay()  --在每次发送request之前调用,如果需要delay,那么delay相应时间;8 H0 w. n! W! @. s1 q3 Y8 Q
function request()  --用来生成请求;每一次请求都会调用该方法,所以注意不要在该方法中做耗时的操作;
9 ^9 i5 x3 O4 s( v( U- B5 \! O: ], dfunction response(status, headers, body)  --在每次收到一个响应时调用;为提升性能,如果没有定义该方法,那么wrk不会解析headers和body;/ e- M  c) F8 a* \1 G& {: k1 @6 Y& Y
* o: [$ U3 W+ P1 H5 ^% P
; q9 B6 X: u% s( Y3 `+ S
结束阶段
4 ~2 ~! S% \. ?" z1 Vfunction done(summary, latency, requests)  --在整个测试过程中只会调用一次,可从参数给定的对象中,获取压测结果,生成定制化的测试报告。
2 r' x8 M' ^) D4 l) ^" H+ _   % k  @! \1 B! e8 k0 `# V
: I3 z7 x) @/ r) c, A
  2、自定义脚本中可访问的变量和方法:
* [% w" Y' L5 S* I( I) J) f3 {7 M: H0 \4 W
  变量:wrk+ r2 \" [8 k& y
+ i" v- s3 B8 A6 Y) L# A, \- Y5 t
复制代码
* Z  `/ k9 K- i9 \! x) U, u& lwrk = {
! \! O! n1 K& q0 H    scheme  = "http",
+ [* p1 @; V  \: P( @    host    = "localhost",5 ?3 R# H' c) ?  q
    port    = nil,
( e1 ]4 G5 J4 F- k3 L    method  = "GET"," [  |1 Y5 n3 S5 k# d, x
    path    = "/",# F3 e& A' W0 F. i+ {2 I9 n
    headers = {},
2 Q( k9 A: ?# @/ u    body    = nil,
7 s" S. b+ U* t4 ?4 h  t2 z    thread  = <userdata>,
  s! j/ M- }( S) |9 |  }
+ x$ I1 ]% U7 e* y复制代码
% z* g3 ?) O' e& l9 O2 z ! ~$ T" U% k1 Q8 h

# r5 ^. j9 G3 n& ]  方法:wrk.fomat wrk.lookup wrk.connect                  
2 r4 H4 y, r; f7 l1 q* j4 M# l
7 c' u6 \! t- ]' y8 Z# Qfunction wrk.format(method, path, headers, body)  --根据参数和全局变量wrk,生成一个HTTP rquest string。
  q! b$ [" A: w0 E1 ufunction wrk.lookup(host, service)  --给定host和service(port/well known service name),返回所有可用的服务器地址信息。6 k1 M3 ^  e* R# Q& m
function wrk.connect(addr)  --测试与给定的服务器地址信息是否可以成功创建连接8 W( ?, u' b& S+ V* A1 b
3 |& T3 O& h; d1 a7 {0 \5 T

6 f7 u( j5 O5 x3 z8 j3、lua脚本压测实例
, P) W3 U3 I) T+ C; n
4 q0 w0 [# O% m7 [  压测命令:wrk -t8 -c200 -d30s --latency  -s test.lua http://www.bing.com: A, A. x9 G# h! N

+ n( o: K$ A2 U* F  test.lua是用lua写的压测脚本,如下是压测脚本的实例:
8 O! Q5 X2 m# g7 o( Y2 X- [3 ?1 S) C0 u& }3 J+ m& g  F* ]
  使用post方法压测
2 d% j* o8 V7 U6 m* |$ J$ c5 F! _' r) X& j8 r
复制代码
2 R# n6 }( Y/ F( T& P  twrk.method = "POST"
- Q- S, w1 I, e; x8 N, Rwrk.headers["S-COOKIE2"]="a=2&b=Input&c=10.0&d=20191114***"
/ q* q- l2 P1 E* p. g" {' Y+ P/ ywrk.body = "recent_seven=20191127_32;20191128_111"
* l4 t2 y3 Q9 M3 n0 R4 zwrk.headers["Host"]="api.shouji.**.com"
! G' r- V; Q- J7 y5 B
5 ~# [9 \( l4 r2 V' Yfunction response(status,headers,body)2 d/ n8 v, [  x
        if status ~= 200 then --将服务器返回状态码不是200的请求结果打印出来7 l& G1 a! x7 p1 \' [' q. F0 G
                print(body)6 M) R; T2 ~5 _/ x+ ~. E
        --      wrk.thread:stop()8 Q5 O7 ?7 P' f- S
        end
" e  _9 `% c3 Send
$ x3 Y0 ]& a& }1 B复制代码
' Q; k, K  X$ z5 m3 k3 {8 O
/ U8 V; b$ l- U
! E9 ~6 |7 ]5 [. B1 ^   发送json
8 c6 P1 `4 L4 |/ @; [  v
7 `* f' Q4 |4 p; c7 E2 T& K; T复制代码
0 x2 D/ ?" I2 l7 m) Z) h# Urequest = function()
3 Y1 G+ C1 b+ ]: v* k    local headers = { }
, {1 z  D! X* V: Z6 B% p6 A    headers['Content-Type'] = "application/json"- L3 o1 y5 b2 v) p$ W& v
    body = {* P2 q; z: G& B5 R4 D' h2 R
        mobile={"1533899828"},5 m7 Q8 n! ?$ M: |2 ?- ]  Q# u$ ~
        params={code=math.random(1000,9999)}
. m. Z6 K9 I* {: L    }
5 b: E9 b/ B3 V& W- u) R    local cjson = require("cjson")
9 [+ Z8 y* ^, ]# G6 I, o    body_str = cjson.encode(body)/ C4 l- q; Z- R: `0 N; H7 v
    return wrk.format('POST', nil, headers, body_str)
) X4 c& u+ d2 `% pend2 _( ^$ D3 N% a; h! K
复制代码# E1 f% W' d2 V5 y

: b- D8 P* y* t/ Q/ f, T( J  M% H6 l4 n: u
& o8 t  x! e  M' U0 Q5 }; ywrk读取文件,实现随机header-cookie
5 R& J  X2 F. O# k. L6 Q! F- z) l" @1 D: `8 A3 D* X
复制代码2 E& E. z1 J( `9 B$ k- a# B
idArr = {}1 \3 `! b- H, R- b' P, B$ j8 i
falg = 0
" [2 ~" o  @7 f. \1 ?wrk.method = "POST"
  w7 S/ s. N4 d/ J, owrk.body = "a=1"' y2 V$ i: G$ v
function init(args)- V0 b5 i1 R6 q) u  N
        for line in io.lines("integral/cookies.txt") do  @; w  a2 U  w$ _3 d
                print(line)
1 d/ e4 l5 w( j$ d, _$ T/ [                idArr[falg] = line9 f$ _# r! Q( r' y- U# U
                falg = falg+1: E( H2 {0 m! L, r/ r
        end
8 i- {8 K; j" P        falg = 0
1 k2 c7 P/ y, iend
: q* m9 Z* k: o; V" I. I( ^
( I# B, ^1 [: L--wrk.method = "POST"  g" d! \- v3 e, h! q7 B
--wrk.body = "a=1"
) S0 Y7 o% `% \, \$ L; h--wrk.path = "/v1/points/reading"# j3 B' i/ @5 ]" g
/ S) R5 {; M$ }& d4 U
request = function()
6 i/ o" x( O! {3 Y) u4 |& n! g        parms = idArr[math.random(0,4)] --随机传递文件中的参数
& l9 Q! k% F* R! B4 m        --parms = idArr[falg%(table.getn(idArr)+1)] 循环传递文件中的参数! u# z9 [4 y9 a0 F3 {$ f) y
        wrk.headers["S-COOKIE2"] = parms7 @8 X" _# F6 o5 E0 [* V
        falg = falg+1
9 r9 s7 T, A+ K/ A9 c& s        return wrk.format()1 c% _8 r! }# X) Z  O8 F3 y
end, e5 S3 L1 H$ u. F
复制代码
+ {$ q/ w3 }- i; g- I! Y
: \. S' u" y: O9 P% F. ~6 @% V/ q
( i% P8 A/ v* u" n  wrk创建数组并初始化,拼接随机参数8 {/ L9 U& b+ X) M& b! q
! @5 f; u, P; |5 ?. e: R/ @/ ]
复制代码8 _$ S' m' B0 U, Z9 O9 N4 [
idArr = {};
3 `, ~7 E# a; A" j1 Z& mfunction init(args)
& s% m3 R  y9 ?5 C        idArr[1] = "1";
; {2 C1 q1 c' u1 m! a( [' M% ?& a7 z        idArr[2] = "2";
6 _; Y( J2 s2 B3 c        idArr[3] = "3";' J+ F4 e' |3 k9 W- t1 H. ?
        idArr[4] = "4";/ O% ~5 G' `+ o/ y6 T& b: q
end4 V2 M# N) s  t  z# M

- p. f  o" R7 k/ U' Irequest = function()
9 ^2 S* v: T* t7 F: r8 P3 u        parms = idArr[math.random(1,4)]/ a% k8 _+ x' z8 a7 n) t
        path = "/v1/points/reading?id="..parms  r- V$ l: f( @+ a" O6 I- w
        return wrk.format("GET",path)7 s, z$ e# I0 V' s3 K- U
end$ B8 v! h0 X4 C. N5 q
复制代码
您需要登录后才可以回帖 登录 | 开始注册

本版积分规则

关闭

站长推荐上一条 /4 下一条

北京云银创陇科技有限公司以云计算运维,代码开发

QQ|返回首页|Archiver|小黑屋|易陆发现技术论坛 ( 蜀ICP备2026014127号-1 )点击这里给我发消息

GMT+8, 2026-4-8 21:38 , Processed in 0.051960 second(s), 22 queries .

Powered by Discuz! X3.4 Licensed

© 2012-2025 Discuz! Team.

快速回复 返回顶部 返回列表