找回密码
 注册
查看: 3364|回复: 2

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

[复制链接]

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
发表于 2020-11-11 17:00:13 | 显示全部楼层 |阅读模式

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

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

基础使用
" {8 B$ n! f% `% D2 U) ?, W+ y使用类 Unix 环境,在 CentOs 或 MacOs 上进行测试

wrk 开源 GitHub 地址: https://github.com/wg/wrk
" E, G  o8 j' ^0 X: Y通过 git clone 的形式下载 源码包,进入目录下,执行 make ,然后开始编译安装,等待一会即可完成。

wrk 使用参数说明+ n- l1 ?) x( b
-c, --connections:  总的连接数(每个线程处理的连接数=总连接数/线程数)1 ]3 u9 y3 h) L. L! _% h
-d, --duration:        测试的持续时间,如2s(2second),2m(2minute),2h(hour)  d8 S  ]6 Q, J
-t, --threads:         需要执行的线程总数) j: v1 d. [* N* R
-s, --script:          执行Lua脚本,这里写lua脚本的路径和名称,后面会给出案例
# w6 W* @8 c3 A. z! g9 j-H, --header:      需要添加的头信息,注意header的语法,举例,-H “token: abcdef”,说明一下,token,冒号,空格,abcdefg(不要忘记空格,否则会报错的)。) I, _. S) C% ~; g5 c
--latency:     显示延迟统计信息
( v) x6 a0 |! ], u" s--timeout:     超时的时间
" E9 y2 p' F- ?( V* |例子6 Z7 g' Z6 [' Y0 Z: b! R
wrk -t12 -c400 -d30s http://127.0.0.1:8080/index.html
! u1 \) A7 N2 h* R) F$ k! B该请求意思为: 使用 wrk 使用12个线程,400个连接,请求 url 30s

压测结束后的结果:4 ]% d) j% Q5 {: l2 x5 D0 O! H- Q
Running 30s test @ http://127.0.0.1:8080/index.html
  }- y  }8 J* k  12 threads and 400 connections
" R" L$ ^1 j/ _; _/ R' X" j# x  Thread Stats   Avg      Stdev     Max   +/- Stdev0 v2 Q6 ]0 i( V5 Q$ E7 h: g
    Latency   635.91us    0.89ms  12.92ms   93.69%' W) g7 w% ]% T% _: ^1 T! H8 ^
    Req/Sec    56.20k     8.07k   62.00k    86.54%
8 S% Z* S6 ?* ]8 u, r3 A& e% C3 N( ^  22464657 requests in 30.00s, 17.76GB read" L* t; m0 _% l" k, V. L
Requests/sec: 748868.537 _  D( z) _1 H6 |
Transfer/sec:    606.33MB3 H' R5 U  E5 H5 k6 {
返回结果说明:

Latency:响应时间Req/Sec:每个线程每秒钟的执行的连接数  A# v: }3 H9 p" {/ Z$ y$ `0 L% t! U
Avg:平均
& V0 a+ |1 E; G: P7 e, q$ F9 cMax:最大
3 u% V  [9 s0 t+ OStdev:标准差+/- Stdev: 正负一个标准差占比
) O5 I: R* r6 [+ C9 URequests/sec:每秒请求数(也就是QPS),这是一项压力测试的性能指标,通过这个参数可以看出吞吐量$ X6 g# B& x' t: Q. Q# ]
Latency Distribution,如果命名中添加了
2 u! F5 T( i0 i  g* ?4 \/ klatency就会出现相关信息
2 W' n1 A) v& j实战1 S( p2 ?7 p+ F2 o9 e9 S& M6 E
使用 wrk 对鉴权的接口进行调用压测。由于是鉴权的接口,需要根据密钥和时间戳动态的生成 secret 然后对后端进行请求,才能通过验证。这里我们引入 lua 脚本
) K7 @# u6 A" {" @- y% s1 f由于 wrk 工具里面 自带 luaJit ,所以我们不用下载。但是需要 md5 的模块,所以需要使用 luarocks 来管理和下载 lua 模块和包。

安装Luarocks 包管理工具: g% P# P3 t3 J4 u9 ]  r" {
LuaRocks 是 Lua 模块的包管理器。它允许您将 Lua 模块创建并安装为自包含包(称为 rocks )。您可以在 Unix 和 Windows 上下载和安装 LuaRocks。官网:https://luarocks.org/

通过 curl 下载4 O3 b" P4 y; S# |) A
curl -o luarockt-3.0.3.tar.gz http://luarocks.github.io/luarocks/releases/luarocks-3.0.3.tar.gz! S( j' f0 R- a  S& \
解压 luarockt-3.0.3.tar.gz后,进入目录下 指定到 wrk 里 LuaJit 的目录进行 configure

//这里指定你自己的 `wrk` 路径/ j$ h$ b7 u& l
./configure --with-lua=../wrk/obj+ @4 u4 |. e/ x) y
编译安装1 U0 w/ L, w# X, M" r$ Z( H
make install, v! k* U  i8 x1 Z% v! e
通过 Luarocks 安装 md5 模块
' \6 r6 h# O  Z5 gluarocks install md5

开始请求
: {" `* L8 {/ k3 }( b. j我们需要像 url http://127.0.0.1:9000 网关进行 POST 请求,该网关会对请求进行鉴权和验证,并判断请求的实效性。所以我们需要在请求时动态改变请求参数,因此需要结合 Lua 脚本。

Lua 脚本 helloDemo.lua
4 ?6 x6 X9 O! q5 y3 Y7 Wmd5=require("md5")! ?/ E: [% H2 \5 T
-- md5加密,拼接请求对象
7 W- \; q7 X3 q0 ]: E' m: gfunction buildJson(json)- A+ L& d% s, U  A: F6 N
  local apiKey = "abcdefg1234567"- R$ s. \4 F* Q1 o- w6 ~
  local password = "qwerxxxx"% d7 p" h) K8 j" R- |  L
  local timestamp = os.time() .. "000"7 z3 k7 z# C% m; h" D0 ~; `
  local secret = md5.sumhexa(apiKey .. timestamp ..  password), j; z, z3 Y8 [0 i) R- P  @5 s6 _8 F  X
  local body = json .. "×tamp=" .. timestamp .. "&secret=" .. secret8 G- t- G) B% C% r( l  y
  
/ K4 z  n; U1 q  y  ~, g  return body
: u0 T5 l/ d: y* kend

wrk.method = "POST"
. v) ^1 D* r$ @$ r( s- d: iwrk.body = buildJson("serviceName=com.github.dapeng.service.HelloService&version=1.0.0&methodName=sayHello¶meter={\"body\": {\"request\": {\"bizTag\": \"order\", \"step\": 100}}}")
; G/ g0 {1 y( qwrk.headers["Content-Type"] = "application/x-www-form-urlencoded"
; a) c8 [- R5 E* J' v! q- i$ W: c5 ~请求脚本

#!/usr/bin/env bash" }  P+ L4 {  E& L) n
time1=`date +%s`
, i$ _5 w3 p  c9 j# |' Iecho "开始时间 `date +%Y%m%d%H%S`"8 \" m0 v  d1 p% _
# wrk 安装目录 -s 后指定上面写好的lua脚本/ N$ l5 H2 U0 E- i2 q
~/ideaspace/dapeng/benchmark/wrk/wrk -t4 -c400 --timeout 5s -d 60s -s lua/$1.lua --latency 'http://127.0.0.1:9000/api/e1bfd762321e409cee4ac0b6e841963c'5 P0 j7 n1 Q$ O1 {3 q
time2=`date +%s`
+ Q. M! ~, U2 s6 ~. GuseTime=$[time2 - time1]
, t: z. h# ~. r! h& k: ?: c7 Uecho "结束时间 `date +%Y%m%d%H%S`"& j. m+ u, ?1 J- R- @
echo "总共花费 $useTime s"3 f: l$ D" S. q7 d' g3 ^  R
执行脚本

sh start-wrk.sh helloDemo
! c7 c: P8 P6 `/ Z7 P7 M& d通过上面方式,我们就可以开始请求已鉴权的接口

总结
6 n/ Z2 [  d  Q" Q$ O" cwrk 是一款高性能的 http 请求压测工具,它使用了 Epoll 模型,使所有请求都是异步非阻塞模式的,因此对系统资源能够应用到极致,可以压满 cpu。- c8 K  f6 o& @; W5 Y  {6 L
wrk 可以落站使用 Lua 脚本。该特性可以使我们通过 脚本动态的改变请求参数,对请求压测提供的多样性的选择和定制。

后续# X3 J# j; @& ?7 P8 Q- r' s
1. 去除 CO7 T" k; k/ E3 w$ Q$ \& [' ^
关于 wrk 测试延迟分布不准确的问题,涉及到 Coordinated Omission 的原因,可 Google
: J* c- p. b; Y在 src/wrk.c( U. r+ E5 b+ z" H
将下面部分代码注释:8 Y! o9 c$ ~) k- Q% {* [! U
//  if(complete / cfg.connections > 0) {
% a7 [) l6 q* x- z* `1 t//       int64_t interval = runtime_us / ( complete / cfg.connections);! W; c  x  s) m" [
//       stats_correct(statistics,latency,interval);/ O- F9 R# I6 |
关于 wrk 测试延迟分布不准确的问题,涉及到 Coordinated Omission 的原因,可 Google,也可以参考 wrk2


) j4 @2 N! @& Z" X0 A! b$ i7 a( I9 w% }1 x
wrk入门总结: L+ f; G% y/ j! j, I5 o

# C! E2 q( F$ p& H5 g! G一、功能介绍:

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

二、安装过程:

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

$ M: F8 ^" e8 g" w1 K; n
  • make编译过程中问题解决:

    1. -bash: make: command not found

    [root@XXX wrk2-master]# make-bash: make: command not found
    ' v! G7 |2 j8 p, A. d/ f. W

9 p: c- J5 p+ l: u+ L  w

  系统无法使用make,make install,一般出现== -bash: make: command not found ==的提示,是因为安装系统的时候使用的是最小化安装,缺少make、vim等常用命令。% b' R% G6 c; N$ a$ @
  直接安装make即可解决问题:

[root@XXX wrk2-master]#yum -y install gcc automake autoconf libtool make  L+ w. a' C4 B" ~! r4 F3 H: h! i  b
  O4 u$ Y8 F* A3 s1 U" o2 @

  安装g++:

[root@XXX wrk2-master]#yum install gcc gcc-c++
9 H; [2 A$ S6 e1 B
  ]% k  I! {) i4 _7 l

2. src/wrk.h:11:25: fatal error: openssl/ssl.h: No such file or directory
8 J  R3 A: F! T$ ghttps://img-blog.csdnimg.cn/2020052220505566.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NjY2NzeTk5,size_16,color_FFFFFF,t_70% i' I6 l) l- X: g1 z
  问题在于:系统中缺少openssl库,安装即可

[root@XXX wrk2-master]# yum install openssl-devel  或者[root@XXX wrk2-master]# yum install libssl-dev2 k+ G- J! Z+ A) l2 b3 z

) A, H1 `4 H9 x1 G3 H5 Y0 \/ w三、wrk 初步使用
  • 基本用法:

    Basic Usage: wrk <options> <url>

    Options:                                                -c, --connections <N>  Connections to keep open& H" V' o" G' W
     # HTTP连接数,如1k,1M,1G,    -d, --duration  <T>  Duration of test  
! {% e5 X' Y6 V9 t+ g- M    # 测试持续时间,如 2s 2m 2h              -t, --threads <N>  Number of threads to use  ) ^% `- B2 K, b0 i- o6 C
    # 开启的线程数                                                           -s, --script   <S>  Load Lua script file
2 y6 c+ X9 @& V  \1 W& G: z7 s  # 进阶功能,使用 lua 脚本    -H, --header   <H>  Add header to request  
" Y% f6 Z  G! m8 l, a( ^7 R& J  # 添加请求头                    " e7 ?2 V. V! {0 ~7 m9 O
# 打印详细延迟统计    -L  --latency    Print latency statistics       -U  --u_latency  Print uncorrceted latency statistics                     ==  `4 s* m: c; Q7 V2 X: @
# 设置请求超时时间,大于该时间的请求将被记录==          --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)    ( D$ o- }7 Z' U6 @
#工作速率(吞吐量)即每个线程每秒钟完成的请求数                           in requests/sec (total)                               [Required Parameter]
  F. S4 N5 S; A8 m9 U2 _5 K0 Y3 y5 T) O* s4 G; \  h
  • 使用方法–readme
    ' ]  C$ _1 r' N* c9 @3 E* `5 j0 T
[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个请求延迟标识,延迟百分比
# m3 P" ?5 p+ W- O1 q4 @1 b
四 测试场景
  • 测试HTTP协议网络的性能[root@XXX scripts]# wrk -t2 -c1000 -d15 -R1000 --latency https://www.baidu.com/
    * g# Z/ p0 C' H' ?- A6 g
    • 1$ z3 O  i" U& K/ n3 u. d# Z
    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
8 h) K; y3 R8 z5 P; `2 ~/ W& k

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

  • 测试当前服务的最大QPS

      进入安装目录,运行

    $ S5 D( c+ t- D6 g7 `  \
[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
$ u9 q: o0 Q8 L- ~" w# q9 R  Y

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

  • 使用Lua脚本个性化wrk压测
      n8 |1 N0 Q( V  d

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

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
 楼主| 发表于 2020-11-11 17:00:14 | 显示全部楼层
软件简介5 H+ |. f7 E! d6 c- x# @6 v' l4 W  E
wrk 是一个比较先进的 HTTP 压力测试工具,当在单个多核 CPU 上运行时,能够产生大量负载。它结合了多线程设计和可扩展的事件通知系统,例如 epoll 和 kqueue。
5 p* m; R$ p0 p+ k
1 A7 F$ I" }6 f4 V& C) L可选的 LuaJIT 脚本可以执行 HTTP 请求生成,响应处理和自定义报告。
; Q4 E6 p4 m3 i6 N1 P- ^
; }! ^& r$ n5 J) f测试方法:
1 }! n% Q6 F0 \) z( f3 |
( B  G. H1 P- c) c& P* \6 T3 i+ Z6 iwrk -t8 -c400 -r10m http://localhost:8080/index.html) i) T. O& k( h/ z
输出结果:+ `: l5 y' k" Q$ ?* c! z- y
; C5 n: T) e' r. V) e* L
  Making 10000000 requests to http://localhost:8080/index.html
- P2 D' M! u6 w8 K2 p- M0 R3 W    8 threads and 400 connections7 H2 ]6 i+ z- _6 p2 U
    Thread Stats   Avg      Stdev     Max   +/- Stdev
# U5 K2 m6 I$ {- I; T2 _) A      Latency   439.75us  350.49us   7.60ms   92.88%4 k5 z5 |* G# m) C
      Req/Sec    61.13k     8.26k   72.00k    87.54%
1 [4 u& b6 p2 [' {    10000088 requests in 19.87s, 3.42GB read' H& V) J  H5 z. x% A- O
  Requests/sec: 503396.237 w: E4 G8 R) r% g, `5 |+ |* @
  Transfer/sec:    176.16MB
1 r  l. j1 ^+ d* @1 ?

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
 楼主| 发表于 2020-11-11 17:00:15 | 显示全部楼层
一、简介
9 Y% Q! b7 U! h* l6 O/ `" ^% F4 p: `* E
  wrk 是一款针对 Http 协议的基准测试工具,它能够在单机多核 CPU 的条件下,使用系统自带的高性能 I/O 机制,如 epoll,kqueue 等,通过多线程和事件模式,对目标机器产生大量的负载。5 o! g9 S& x; `5 u% m5 U# ?# x1 G

/ u, |0 U0 k: m/ a! H$ {1 vwrk是开源的, 代码在 github 上:https://github.com/wg/wrk
- ~8 ]6 ?, Q9 w
: g9 V1 v; d8 |9 d3 I% F安装:https://www.cnblogs.com/savorboard/p/wrk.html1 P0 @7 T$ o  ?! I$ `
1 a% N% u" b( _
% U1 j, r2 Y1 a& |/ ]4 W! f* Q

) f; I, F6 ~2 W: l2 L优势:
9 @9 Y4 n& ]3 i" n- T2 e. t6 I, S
5 b' A0 d' b7 F  E, w2 M轻量级性能测试工具  a3 w  |9 A4 Q* T* v2 Q
安装简单
/ T7 L! X0 i  q% m学习曲线基本为0,几分钟就学会使用了
8 W0 B- S. s, C& B8 H基于系统自带的高性能I/O机制,如epoll,kqueue,利用异步的事件驱动框架,通过很少的线程就可以压出很大的并发量,例如几万、几十万,这是很多性能测试工具无法做到的。8 E) [. u1 \8 x3 P7 e) l
劣势:6 A$ y, b2 l( w

2 G% f" J/ W- E# }wrk 目前仅支持单机压测,后续也不太可能支持多机器对目标机压测,因为它本身的定位,并不是用来取代 JMeter, LoadRunner 等专业的测试工具。2 C% D, `7 p2 b" h# J
  d2 ?( C$ t2 D+ X- o7 e2 Z( B
) w( I' [8 F4 {2 e+ e
二、格式及用法
4 d- W5 @2 ^  L; M; P, V8 R6 E; N5 E4 v) Z6 E8 R* t' P# D
复制代码
* e4 U% x" q, C5 N3 p8 V7 h1 qUsage: wrk <options> <url>                           * ^) S! [* O7 f( C( c

: n+ V/ }$ J: T, o& E$ x  Options:                                           ) s; V! Y. ]5 o/ _. n% {
    -c, --connections <N>  Connections to keep open  
; Y% s2 M! v) n6 s2 Y    -d, --duration    <T>  Duration of test         
2 R8 `, C, o) m, D$ \    -t, --threads     <N>  Number of threads to use  5 V5 S8 W/ U3 n5 X: a! E0 [. l
                                                     
6 N0 ^7 Z# U/ t' S    -s, --script      <S>  Load Lua script file      
' y- a8 |1 R9 x    -H, --header      <H>  Add header to request     
) Y) }8 K3 a/ N- y% X        --latency          Print latency statistics  
+ t0 p- Q  V2 k% [3 A        --timeout     <T>  Socket/request timeout   
/ o+ _" M& ?4 l; |7 y* h; O    -v, --version          Print version details     $ s9 m9 f# {% p! o1 E/ ?# h- L
                                                
$ ~. U& T; ]7 y  Numeric arguments may include a SI unit (1k, 1M, 1G)4 |/ h: P- [" h$ s3 C0 R6 {; {
  Time arguments may include a time unit (2s, 2m, 2h)
; s7 p, F9 c% M$ P1 a& n复制代码& Z  p% Y3 i7 ^, e) N3 E
- D1 X* A" q/ z$ W) U* J" G

' m5 {6 z, u% c; F& @$ \翻译成中文:- V7 p1 a2 y, a4 h" O- z

/ f8 w9 ?5 L  J& L复制代码
  O% c: _% }) Z( {: p. {使用方法: wrk <选项> <被测HTTP服务的URL>                           + }% X+ B) c5 |( P

( \" \3 ?( ]1 z  a  C  J3 ^  Options:                                           1 L- {$ M. a  W2 I/ Z/ v: B# e  [
    -c, --connections <N>  跟服务器建立并保持的TCP连接数量 # L( K/ x1 J0 |/ C; ?7 z" e; @
    -d, --duration    <T>  压测时间         
$ n3 U4 Q2 R$ v- L    -t, --threads     <N>  使用多少个线程进行压测,压测时,是有一个主线程来控制我们设置的n个子线程间调度  ( c8 P! e8 h4 D) H
                                                    ( x  {+ p6 E- _* d+ \# I9 Q1 ~  L
    -s, --script      <S>  指定Lua脚本路径      
, W8 G6 V) V6 V7 y/ F+ x% v3 X    -H, --header      <H>  为每一个HTTP请求添加HTTP头     ( g4 U2 O# \' q# o( o$ C
        --latency          在压测结束后,打印延迟统计信息  
7 s( m) A3 C4 @7 e! e" n5 ]: c) @        --timeout     <T>  超时时间   
; W; j! @3 V' q$ V- Q    -v, --version          打印正在使用的wrk的详细版本信                                              9 Q- f8 ?, z+ ~
/ q, a9 N% z+ ^6 B" k
  <N>代表数字参数,支持国际单位 (1k, 1M, 1G)
. U- ^/ ]% E  q3 F0 t* d8 o  <T>代表时间参数,支持时间单位 (2s, 2m, 2h)
" S, g. I1 i* q+ T+ |1 A4 I复制代码
) ~' S! @4 |" e - y* i+ }! c) s8 p
, E3 _; t0 S4 V1 w

2 C: @% r% r  z* e6 `* y5 R( g3 \- u7 D; a0 p+ Y$ D/ y
三、简单压测及结果分析! d0 |% y; K; T5 j% @$ m
; j1 L; a, ^" k; @* o
做一个简单的压测,分析下结果:" p* R( {: ?% @( _1 n. _6 M

  ^" \/ b" Z' \& O: k5 |wrk -t8 -c200 -d30s --latency  http://www.bing.com
, x8 G. s  s1 i* \0 H * S5 b* ^9 k/ y& W) d, p" k
6 G" N" m# r; Z0 l: E* f- D, |
输出:
" F( }' U( K4 j) {1 t% }3 g4 f7 W# j5 b& n2 M$ ^
复制代码
* O7 |$ W* C  \5 wRunning 30s test @ http://www.bing.com
0 L# s, U* J0 V& f  o% \4 l! q- J: h
  8 threads and 200 connections
- }, f6 e9 R- Q) A- l$ ]
$ E6 t8 @3 G. g; G8 |! s' W  Thread Stats   Avg      Stdev     Max   +/- Stdev# r' O& p  G% ?
    Latency    46.67ms  215.38ms   1.67s    95.59%
2 d2 f+ `2 ^2 }! T5 J    Req/Sec     7.91k     1.15k   10.26k    70.77%! G# `3 g$ P  H$ a3 R( ~; d% T# ?

# \' N/ W5 r0 x" J  Latency Distribution
1 O& R) G. K# T, c' ]4 b4 p     50%    2.93ms; D) o! U' a' \; X3 C
     75%    3.78ms
$ g! `7 t2 g9 Z- i: R     90%    4.73ms
2 ]4 @# L9 f. I: r: |2 {* c" w4 a3 f, K% r     99%    1.35s
3 R% o" ^! m7 H9 a  1790465 requests in 30.01s, 684.08MB read& H# s: l+ ]. A
Requests/sec:  59658.29  {% y$ h1 o3 f2 |2 l" e  z
Transfer/sec:     22.79MB
1 k& P; _" t" t; z9 @3 H2 u0 s复制代码
' }* H. ]8 |1 o& I以上是使用8个线程200个连接,对bing首页进行了30秒的压测,并要求在压测结果中输出响应延迟信息。
! q( J5 t* z! Z- J% U, n; C0 \" A9 S$ J" X: g
以下是解释压测结果:  C$ ?! g# l: f) N( s8 J8 ?& x
# F# ~4 {. z% W' H* o5 v! W
复制代码
. u, |- ^1 r3 G" n2 lRunning 30s test @ http://www.bing.com (压测时间30s)
9 K  l. t8 k+ z/ T" ]+ E9 P6 o! u" W/ D4 k9 p4 @9 ?
  8 threads and 200 connections (共8个测试线程,200个连接)
* J% O  j% y$ z! [- E" W4 o  L1 b7 ^9 J6 Q3 F8 T! e
  Thread Stats   Avg      Stdev     Max   +/- Stdev# `! [# O' d5 C
              (平均值) (标准差)(最大值)(正负一个标准差所占比例). U& S1 I  a# |; T# q9 N
    Latency    46.67ms  215.38ms   1.67s    95.59%) E4 t7 S* ^) @( E1 r' l& k$ m0 `
    (延迟)$ w+ k2 E6 D" S
    Req/Sec     7.91k     1.15k   10.26k    70.77%
# N: }  C& h! M: m1 ^    (处理中的请求数)5 _% x& r2 c7 |% @- v# V, p. z

- G5 [' B; I* f$ ]& c% J% M$ X  Latency Distribution (延迟分布)& _) |" |1 S' x0 @0 k
     50%    2.93ms
7 p) b2 X3 g9 k7 r) w) D$ Z. N     75%    3.78ms: @4 z* ~" q" I, W- f7 G; d
     90%    4.73ms( X0 I  P, J! i
     99%    1.35s (99分位的延迟:%99的请求在1.35s以内)' y7 Z- [2 @/ U7 Z9 b
  1790465 requests in 30.01s, 684.08MB read (30.01秒内共处理完成了1790465个请求,读取了684.08MB数据)! r6 G. M1 ~# s+ o8 z
Requests/sec:  59658.29 (平均每秒处理完成59658.29个请求)$ z" W/ e: }5 B8 t: H2 ^/ v! f
Transfer/sec:     22.79MB (平均每秒读取数据22.79MB)$ x5 d) d$ P1 m( W, {
复制代码# F7 @; K7 e4 `' J. [2 H% X  u
# P* x" f- z) c9 r
' v: x- J! r' \  C/ T. u/ g
; F2 T2 c# C& i( Z$ t- F- d

2 |& P- r. e& |0 G# p9 l1 U四、使用lua脚本进行压测
+ j; I3 N# W* Z+ L& u! k6 ~% J2 D6 ]% M# n) C# s
  lua脚本是一种轻量小巧的脚本语言,用标准c语言编写,并以源代码形式开放,其设计目的是为了嵌入应用程序中,从而为程序提供灵活的扩展和定制功能。wrk工具嵌入了lua脚本语言,因此,在自定义压测场景时,可在wrk目录下使用lua定制压测场景。3 {. i  }* @& I0 d& E

0 ~7 I1 r& m. a3 y9 Q  1、lua声明周期* A1 L6 k, y# ~2 o! q
" h, @: p' j- m9 v; X2 `
    共有三个阶段,启动阶段,运行阶段,结束阶段。wrk支持在这三个阶段对压测进行个性化。   
( _$ f2 R- ~- I: ?% B( s" b! [- M( J5 L* t0 _# s
启动阶段
% z0 ?3 \$ N- s- kfunction setup(thread)
8 ]- W) p' y$ A0 u" u
( z  \8 Q- A7 Z+ q: k
1 ?9 l9 b7 w) \4 G/ X  K在脚本文件中实现setup方法,wrk就会在测试线程已经初始化但还没有启动的时候调用该方法。wrk会为每一个测试线程调用一次setup方法,并传入代表测试线程的对象thread作为参数。setup方法中可操作该thread对象,获取信息、存储信息、甚至关闭该线程。
- t$ h+ u( M9 F- [' ~$ h( [' F) x- W& G" W" u$ ?
thread.addr - get or set the thread's server address" D  K$ o. u/ [3 ^4 J
thread:get(name) - get the value of a global in the thread's env
% g4 e! Z; S" z3 _- N7 J; f" M7 fthread:set(name, value) - set the value of a global in the thread's env9 z9 K  ?3 c; M
thread:stop() - stop the thread) Y/ o& g& }& j- x  u* W& F
& T  q- K* P( `8 ^0 s+ b

0 x1 r" s# Q; _8 _3 D1 @运行阶段! L9 a9 ?3 C) {2 a4 [1 H
function init(args)  --由测试线程调用,只会在进入运行阶段时,调用一次。支持从启动wrk的命令中,获取命令行参数;
! A# R8 M' o% n' w7 z+ A9 b6 ~8 Sfunction delay()  --在每次发送request之前调用,如果需要delay,那么delay相应时间;
; ~  M! |6 j* S9 c+ Ifunction request()  --用来生成请求;每一次请求都会调用该方法,所以注意不要在该方法中做耗时的操作;3 |; u2 h  Q  U% @3 F5 m
function response(status, headers, body)  --在每次收到一个响应时调用;为提升性能,如果没有定义该方法,那么wrk不会解析headers和body;: ?- p1 g0 [/ s! f' P2 A! m( L
& \. s! H2 H2 d" R1 I& y
: _9 E# M) I' H( d' m2 S8 A
结束阶段
. t! F) v4 q5 w8 Dfunction done(summary, latency, requests)  --在整个测试过程中只会调用一次,可从参数给定的对象中,获取压测结果,生成定制化的测试报告。
5 H& h5 a5 [) p4 J# L+ e; U   
" ~2 o2 P) C! Y4 A' |% [. N( ]5 e  H2 _# n
  2、自定义脚本中可访问的变量和方法:
7 ?+ O" m; o! w$ c4 e' g" K. c3 y' _
  变量:wrk
, m# \; o- `/ `" J7 T, y  \# z3 h/ V. C" P. P" V! U
复制代码
) {5 x3 ?! s5 Jwrk = {: a# p9 D& y' l' |
    scheme  = "http",
2 ~0 ~' j. Q% o: J5 ^# ~0 E3 |+ |    host    = "localhost",7 Q7 t4 X$ E' c
    port    = nil,
, E; o! P6 X& m& Z* p    method  = "GET",
4 f! Y3 n7 F8 f/ P/ h( Y3 e' \" v    path    = "/",
" e" y: R' D6 W/ Z" r    headers = {},
6 A  \0 |. [. ?$ B) @& D% M    body    = nil,
: I3 X3 b) @/ S    thread  = <userdata>,
6 d( m3 J- s5 r0 m' }0 P' k  }: q$ V% Z9 u" V3 G1 G) O
复制代码4 z. X9 z1 w& A; w0 o) b  ]5 Y. g

! y" V& m3 ]: u; v
( k4 X- [: g( o0 K/ v6 Y2 V  方法:wrk.fomat wrk.lookup wrk.connect                  
+ Y6 `! v8 \0 e% w- }* c3 i
% Z% c' @. ^# ?function wrk.format(method, path, headers, body)  --根据参数和全局变量wrk,生成一个HTTP rquest string。
5 ^3 [/ y! [6 z$ ]$ }1 @function wrk.lookup(host, service)  --给定host和service(port/well known service name),返回所有可用的服务器地址信息。  R; s3 c* J/ @, x1 g
function wrk.connect(addr)  --测试与给定的服务器地址信息是否可以成功创建连接7 j& h0 ^* |% i' H

* s* ^  F! Z  Z, X" w" ~: k+ x9 B/ p  Q0 X0 I
3、lua脚本压测实例
' y4 P# z4 F- k! r
6 |" i9 |2 o# S1 s( ?2 @' S  压测命令:wrk -t8 -c200 -d30s --latency  -s test.lua http://www.bing.com
7 Q+ J6 w1 [) ~9 K6 _
" c: X+ N: w1 b7 F7 C& b3 t  test.lua是用lua写的压测脚本,如下是压测脚本的实例:
0 Y: s7 u2 ?0 n  f
# _* S& M5 J  Z( I) Y$ N: ~  使用post方法压测6 g9 Q' b* j8 S% C" o0 C' X1 h* l# k1 f
. R1 d) d5 q) G' ^
复制代码1 c) E" R; a) k. Z: }$ R
wrk.method = "POST"
. T/ \4 c6 x/ r) vwrk.headers["S-COOKIE2"]="a=2&b=Input&c=10.0&d=20191114***"
( P' d* C0 o9 jwrk.body = "recent_seven=20191127_32;20191128_111"2 s8 m' k) m; M( N$ T3 Z
wrk.headers["Host"]="api.shouji.**.com": R3 r. @& N6 f$ U# g8 q3 b

3 W; p) K/ D9 q. V1 `; kfunction response(status,headers,body)
/ z3 _9 S  s# h( I2 |        if status ~= 200 then --将服务器返回状态码不是200的请求结果打印出来% n( C9 V  u" K7 {1 U
                print(body)
* ]; g. Q. E/ S1 ^) `% [. M: X$ }        --      wrk.thread:stop(): [9 a3 h& Y) M7 T
        end
0 A5 O( o) w) J/ U3 vend, P* C" D+ a) w5 \
复制代码
; r/ s* t9 x  w* n# t1 \2 G, x& S 1 B! r& t1 ?3 d! K' S; J8 O
7 d' O; c3 [$ w' Z+ S* o1 W* c
   发送json
4 U( S" f! O  K
+ j$ q) F# E. Y0 H6 g& Z: [' \复制代码
2 l2 N: R- h4 ?6 Frequest = function()
3 ~( Q" \1 O$ x    local headers = { }& C; ?0 {* U* U8 P" t
    headers['Content-Type'] = "application/json"
2 t/ L+ J- q* s, f5 W    body = {1 S6 T( o( }: N5 I% q. J5 k
        mobile={"1533899828"},* ?. {8 q" H1 Z" n3 k% d
        params={code=math.random(1000,9999)}
  b" C8 h3 s, G/ X0 t  ~0 @    }
3 E* i7 \4 d! ]    local cjson = require("cjson")$ ^0 i8 i: i' t, t8 [: f
    body_str = cjson.encode(body)
( N- c; _& _; z$ B- l    return wrk.format('POST', nil, headers, body_str)
. A- O; r$ W  Q4 I, \end
) r# u' K6 |3 ^3 H$ `1 d- u: i复制代码
4 C2 r. i6 c7 S
7 F4 I0 x, {! ~, w! b' }1 C1 Z2 u, C& C& V  ^- G
wrk读取文件,实现随机header-cookie$ |% B4 z9 _( a: `6 @9 }
4 v( r2 ]: _9 }0 x
复制代码! p$ Q- E& ~+ T5 c8 c- t  X1 |  U: d7 }
idArr = {}) c+ I& v9 g3 I  _; y( g
falg = 0
# |  A  X. g9 q1 M- i: M' Ywrk.method = "POST"
4 l8 \4 i' F" ]8 X8 Awrk.body = "a=1"
; D8 N0 O3 g( v6 A' {3 Ifunction init(args)( Y' R$ Z+ g2 X* m
        for line in io.lines("integral/cookies.txt") do
5 @$ K* w; l! Q* \! i                print(line)
9 J+ r- }& k4 _& G+ s+ o0 a                idArr[falg] = line
4 H& @2 Z+ C: _: F! s: F. k2 J* C( Q                falg = falg+1
+ L- q7 H7 Z/ u+ e        end/ |: z" k# x5 m  [% E: m3 {/ D) [, }
        falg = 0$ c. D+ U6 v, \' W+ J% t) O
end
; `' t" n2 b  r# H: [( E$ Z! }" V, \' A
--wrk.method = "POST"
' M5 o% F* v, u" h: O0 e+ \- T--wrk.body = "a=1"
: V- f* L- ]: C2 g) w7 w--wrk.path = "/v1/points/reading"6 b# \% J$ h; f4 d' }- H0 Y
2 X: A, W& G; `/ X! B3 T7 A
request = function()
2 d( _2 Z6 W" V: h- F5 n2 a/ i        parms = idArr[math.random(0,4)] --随机传递文件中的参数
  V3 ]+ V/ a9 y( v* H9 E, r        --parms = idArr[falg%(table.getn(idArr)+1)] 循环传递文件中的参数9 m6 Z1 ^5 H: f% ~
        wrk.headers["S-COOKIE2"] = parms; `/ B  t0 M8 ^2 a  ?  _9 d
        falg = falg+16 F9 n7 H3 r  I  U+ S) X9 }
        return wrk.format()
6 P2 e0 w) D% ]+ kend* e5 I) v6 G5 Q
复制代码
7 e2 `5 ~( X+ [  r' ]: z - w" o' H: v7 k7 A5 u- f2 ~

9 i$ v) d7 ?) z2 Y. y! S; N4 [" S  wrk创建数组并初始化,拼接随机参数# H# w# k) a6 ~) G. m) q: x

$ ?8 j# t* S1 A  G复制代码2 {$ Z6 J( c( t" s; f
idArr = {};
6 L" e7 f+ [, G( }* Kfunction init(args). q' j2 c( d6 e0 F' U8 j2 y
        idArr[1] = "1";7 Z% u3 V/ H+ I8 Q, R8 H/ J1 ~
        idArr[2] = "2";4 U. ^/ J& r+ g  e  I/ a
        idArr[3] = "3";
8 N" {/ W, r, F3 {2 y! l$ ]        idArr[4] = "4";
: [" @. I0 B8 p3 W8 y! wend" k0 L8 [9 X( o& d- P1 q6 L) I- @
. F- |# {. L. V( z# r, ]% T% x
request = function()
& Q7 ^) E3 U. X' a4 [% t        parms = idArr[math.random(1,4)], m! G/ k; g0 @! x
        path = "/v1/points/reading?id="..parms
) c, h8 D' R4 z% Z7 s  b        return wrk.format("GET",path)
: G2 M2 [. m- d. lend
5 N$ _2 x' j( d1 Y复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则

返回首页|Archiver|手机版|小黑屋|易陆发现技术论坛 ( 蜀ICP备2026014127号-1 )

GMT+8, 2026-6-12 03:24 , Processed in 0.021232 second(s), 22 queries .

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

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