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

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

[复制链接]

1

主题

0

回帖

12

积分

管理员

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

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入门总结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
  • make编译过程中问题解决:

    1. -bash: make: command not found

    [root@XXX wrk2-master]# make-bash: make: command not found: ]: J, i: w& e2 J% ^  p/ @6 W% R

/ 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 初步使用
  • 基本用法:

    Basic Usage: wrk <options> <url>

    Options:                                                -c, --connections <N>  Connections to keep open
    $ K+ Z# |* w( n& {3 V+ x/ \$ ?
     # 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.html2个线程,100个连接,持续时间30s 每秒2000个请求Requests/sec: 2000.12
wrk -t2 -c100 -d30s -R2000 --latency url2个线程,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: s
    • 1" a4 s" A% U: D* T
    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
! 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 -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

% 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的高级使用方法

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
 楼主| 发表于 2020-11-11 17:00:14 | 显示全部楼层
软件简介
: _# `3 Q/ b, bwrk 是一个比较先进的 HTTP 压力测试工具,当在单个多核 CPU 上运行时,能够产生大量负载。它结合了多线程设计和可扩展的事件通知系统,例如 epoll 和 kqueue。/ [( ^; ^: F/ z4 c; l3 W
1 _9 i$ M8 V1 h) h
可选的 LuaJIT 脚本可以执行 HTTP 请求生成,响应处理和自定义报告。# I# a6 f6 K. D% q9 _: ~
2 v9 w  U( Y0 g; F9 X2 ]
测试方法:: r; s7 @. Q; ^/ E/ h% @

+ t& c  B. d9 E+ K0 i5 ywrk -t8 -c400 -r10m http://localhost:8080/index.html
7 z2 y) g+ c  o9 P% P输出结果:: t; u7 T0 y+ D$ g. k) v4 _3 I/ j$ Y7 l

3 W  i1 p& B7 i, r, h; d( r  Making 10000000 requests to http://localhost:8080/index.html
% q  E- J0 Z/ Q0 X, s    8 threads and 400 connections
3 j. T* q: G+ \  M" f& O2 `) n    Thread Stats   Avg      Stdev     Max   +/- Stdev  {$ m7 l1 J6 x, p1 r, l
      Latency   439.75us  350.49us   7.60ms   92.88%4 l8 H$ [3 s' Q7 g( l- w
      Req/Sec    61.13k     8.26k   72.00k    87.54%
4 ]( c3 u# z& j7 N    10000088 requests in 19.87s, 3.42GB read8 U$ B- m- Q& k8 Q/ o5 @
  Requests/sec: 503396.23
6 `/ Y0 ~/ ?  m3 k- D( {  Transfer/sec:    176.16MB
4 g! v" E9 b& L9 n

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
 楼主| 发表于 2020-11-11 17:00:15 | 显示全部楼层
一、简介8 F+ [' F- Y+ u5 S) X
2 A# E/ h' |8 I* u
  wrk 是一款针对 Http 协议的基准测试工具,它能够在单机多核 CPU 的条件下,使用系统自带的高性能 I/O 机制,如 epoll,kqueue 等,通过多线程和事件模式,对目标机器产生大量的负载。2 s" Q6 [. N7 z( N0 |

- c! S! U, A2 W! Z2 u! }5 o9 @wrk是开源的, 代码在 github 上:https://github.com/wg/wrk5 Z: g7 {6 _, _" C4 }2 Q% v

  f! r& r! w! r# q安装:https://www.cnblogs.com/savorboard/p/wrk.html6 Y2 z7 _! a* D  d( p  m% s

) x9 g( s2 E' q1 q
) D7 l# v. f0 c% ^$ O6 U3 c
; Z  @+ ^, a8 h: `. s' B优势:
5 M) T  B" }$ v& [! r( b# g
8 p3 B- C7 `6 ]轻量级性能测试工具/ C0 R# l3 p  X4 v# U: d9 ]# X  O
安装简单
# O" q( [+ c( E学习曲线基本为0,几分钟就学会使用了( v" c: O4 c$ a1 z' q" H5 {8 w+ `' S
基于系统自带的高性能I/O机制,如epoll,kqueue,利用异步的事件驱动框架,通过很少的线程就可以压出很大的并发量,例如几万、几十万,这是很多性能测试工具无法做到的。
9 Z; v9 p5 g5 u1 R% W. ?劣势:& P$ o' G! @- u: h% R5 c4 V; x) m/ Z
$ c# Z) f& }* U4 b: w: d% _
wrk 目前仅支持单机压测,后续也不太可能支持多机器对目标机压测,因为它本身的定位,并不是用来取代 JMeter, LoadRunner 等专业的测试工具。2 I: n" p* B4 o' R% I

2 I9 O- ]0 P- x6 k3 B
$ K5 I- y% ]9 d/ b$ Z- B 二、格式及用法( A) {! ]* N7 @) c
( o$ w7 K8 l/ c. G& Y
复制代码- a# d% f5 ]4 B2 _
Usage: wrk <options> <url>                           
* S4 K# P- a4 u* ~
' H. Z0 R( P. _; J  Options:                                          
7 @8 a3 y6 ?6 {1 `  O( @    -c, --connections <N>  Connections to keep open  " b$ x8 I* b' G: S2 B
    -d, --duration    <T>  Duration of test         
/ \$ v( u* h- t! D  _2 G    -t, --threads     <N>  Number of threads to use  
9 x- _4 Y& M' q3 L: [                                                     ! M/ I* G5 D1 |8 U8 p% |
    -s, --script      <S>  Load Lua script file      + G, R8 G$ J# P- |# o3 k
    -H, --header      <H>  Add header to request     ! z  @5 m, r% ~, T0 x9 c! ], A
        --latency          Print latency statistics  
! h+ Y3 X. _# ~  c# z  b        --timeout     <T>  Socket/request timeout   
0 S# i3 }8 F- Y0 V& \    -v, --version          Print version details     $ O' m/ g7 Z% Q. H0 X: T4 ?: V
                                                
) X/ d" q& p9 M9 b! Q6 k  Numeric arguments may include a SI unit (1k, 1M, 1G)' s( a" Q9 g  L7 H' D' M
  Time arguments may include a time unit (2s, 2m, 2h). s& A" U9 ?. ?: p7 w) B% y% ]- Q& u
复制代码
& D9 A" \8 R; Z6 }& ] $ r( P3 \; U9 d, l

. W0 \/ Y1 h0 y% N% @翻译成中文:) ^( A: ?4 g. l( I
% Y: z+ p' ]7 C/ d
复制代码
5 i7 F- ?' ~: `使用方法: wrk <选项> <被测HTTP服务的URL>                           
' T" M! P2 k) j: L) z8 Q
6 b8 g. S) y0 M- {1 c1 |5 n  Options:                                          
8 W3 x8 G$ C% p* P) O. e" x8 x8 E: }    -c, --connections <N>  跟服务器建立并保持的TCP连接数量
8 k- B5 `2 T9 J3 k8 V9 H) n    -d, --duration    <T>  压测时间          4 H$ w$ x. ^7 X1 M  v
    -t, --threads     <N>  使用多少个线程进行压测,压测时,是有一个主线程来控制我们设置的n个子线程间调度  
1 m. }- q& U" B- q( _: x0 X! W# l                                                    8 L( H* x# |' i+ E
    -s, --script      <S>  指定Lua脚本路径      
" U! o$ B! f! W  a4 T    -H, --header      <H>  为每一个HTTP请求添加HTTP头     # s8 z  |7 l& a  C9 w
        --latency          在压测结束后,打印延迟统计信息  
+ V( T$ N2 x9 k        --timeout     <T>  超时时间   
" C5 |8 A5 w% g. ~" w    -v, --version          打印正在使用的wrk的详细版本信                                              " C' a' D2 u, H, j5 n8 U
4 {. c/ ^, h; V9 V# O" o) ?8 r
  <N>代表数字参数,支持国际单位 (1k, 1M, 1G)7 i' Y1 c! j) \% Z
  <T>代表时间参数,支持时间单位 (2s, 2m, 2h)
( D( D; V5 ~; `( y% `1 }复制代码' [3 @' c9 R7 t" R2 O
, a! J% f$ L$ D2 k# w% e

7 N$ W! {. s! P ) r! O4 C1 D4 ]7 j- A6 ^$ f# m
9 H. R4 E( C4 ~
三、简单压测及结果分析, z3 [* a5 L5 }

! `5 X8 U% M0 a1 T+ m8 N做一个简单的压测,分析下结果:
* \) a6 j6 B1 F" e- e; N
- l1 A1 _3 r2 K# s& a! `wrk -t8 -c200 -d30s --latency  http://www.bing.com' \" B1 y( R( x2 q: P; Z( P1 z
5 `: g# ~) Y! D$ A: A

% `* `- ^/ u# `" {  Z; I8 L输出:/ S, Z/ m' S% L- R7 B$ N

: e1 J! [% r" D9 E8 p' Z复制代码0 J) f, {3 M, {
Running 30s test @ http://www.bing.com  i+ e$ Z- J/ Y* ?0 K
' u$ _* F8 s5 W9 o: b5 T
  8 threads and 200 connections
3 R9 p% J/ K+ R9 C% k3 K! k4 ?+ p0 {1 P5 k" s
  Thread Stats   Avg      Stdev     Max   +/- Stdev! R; v/ c% C" Z5 W9 L0 e
    Latency    46.67ms  215.38ms   1.67s    95.59%$ _( |" k; G5 r, t6 O# _
    Req/Sec     7.91k     1.15k   10.26k    70.77%
" O3 e  j6 \. x
& G8 T) p7 t; m/ C  Latency Distribution
9 ]9 ^4 p: h* g, t5 F% N( A* V     50%    2.93ms
7 f. J! l) A2 `8 R/ r8 Z$ u     75%    3.78ms1 m$ N* Q- i/ x0 F0 J$ l) l
     90%    4.73ms
% P! g$ O" E1 V* i$ G' I. w4 ]     99%    1.35s% u0 [$ Q, Z# [' S* }  R
  1790465 requests in 30.01s, 684.08MB read, ?# l' D0 P  J) H( h* c
Requests/sec:  59658.291 n7 Z/ C' N; @* q: D, ?5 E
Transfer/sec:     22.79MB
2 q$ p$ J. \  [% o6 H$ @% B复制代码/ a$ M2 w1 m! g$ n# @8 C1 O
以上是使用8个线程200个连接,对bing首页进行了30秒的压测,并要求在压测结果中输出响应延迟信息。
: H$ a- o0 a: t& m$ Z4 U
* Q. o" Z( q/ Z+ `/ h. r以下是解释压测结果:/ ^, F2 w( ?$ n5 v1 Y$ s7 m
7 x0 K' X1 N& L8 x3 o
复制代码
: T% j- w3 w* Q2 f0 _" ^5 sRunning 30s test @ http://www.bing.com (压测时间30s)
5 k2 H* H8 r0 K' g+ @7 F
- p) ~4 Q4 ]) x$ D7 @  8 threads and 200 connections (共8个测试线程,200个连接)
+ O) @9 b' q& S+ `, C5 {+ `8 z  x) ^6 x
  Thread Stats   Avg      Stdev     Max   +/- Stdev# [; D" t7 V  U
              (平均值) (标准差)(最大值)(正负一个标准差所占比例)
0 @: b. {# l$ f) H# e    Latency    46.67ms  215.38ms   1.67s    95.59%! d( L% q3 _( ^
    (延迟); s2 H. @; ~$ m0 I  |
    Req/Sec     7.91k     1.15k   10.26k    70.77%) G# i7 A- R1 T5 k2 O# `
    (处理中的请求数)
# _0 s; L- X7 t; ^& s) H8 E+ E$ I  B- Q/ y5 g
  Latency Distribution (延迟分布)$ n1 H0 M% o: M: R: t/ q3 f# c! P
     50%    2.93ms- ?. L+ Y- F9 R1 w) ]+ ]& l0 m
     75%    3.78ms
3 V3 V# {& B; I. a+ _     90%    4.73ms4 t) q/ a' ?/ }; N- q
     99%    1.35s (99分位的延迟:%99的请求在1.35s以内)
" B, [  O) p4 Z: l. J! g# I  1790465 requests in 30.01s, 684.08MB read (30.01秒内共处理完成了1790465个请求,读取了684.08MB数据)( J" S! ?- u$ ]+ K- H
Requests/sec:  59658.29 (平均每秒处理完成59658.29个请求)
: `$ R" F. b) h5 O, k+ BTransfer/sec:     22.79MB (平均每秒读取数据22.79MB)0 l8 X& P: Y  f8 x! I
复制代码+ I" i$ W2 ?% W

2 J1 a4 W/ q# i4 _9 a7 N  A; Y& a% F8 L; q$ \8 Z

! f( m! Z/ O! U
. Q5 g/ W# }$ F2 L5 E2 n( F3 A四、使用lua脚本进行压测
& u; H7 l' D) {! t) Y
8 N, h& e$ l  \  g1 C  lua脚本是一种轻量小巧的脚本语言,用标准c语言编写,并以源代码形式开放,其设计目的是为了嵌入应用程序中,从而为程序提供灵活的扩展和定制功能。wrk工具嵌入了lua脚本语言,因此,在自定义压测场景时,可在wrk目录下使用lua定制压测场景。" ^& V& Q" T& i/ _1 Q- L$ Q
3 t- I6 K+ v5 ^3 r- J/ v
  1、lua声明周期5 W0 W" t: H0 v( }, j

" p: `. S- s- [* \    共有三个阶段,启动阶段,运行阶段,结束阶段。wrk支持在这三个阶段对压测进行个性化。   0 g+ s9 p: k/ P

/ g/ f$ B0 a, \4 R  f% f- d; U0 f启动阶段! o& M" s' f! [' [2 \+ h
function setup(thread)
0 o& P. F' ]* E
3 k+ J7 Y- v( c( c- G
  Q: O( r+ Y6 T! E- \$ R# z. x" U* z在脚本文件中实现setup方法,wrk就会在测试线程已经初始化但还没有启动的时候调用该方法。wrk会为每一个测试线程调用一次setup方法,并传入代表测试线程的对象thread作为参数。setup方法中可操作该thread对象,获取信息、存储信息、甚至关闭该线程。
" r7 T0 ?1 `8 M0 _8 e* V, w6 E& `4 |8 K% j6 s" a3 c+ e! d
thread.addr - get or set the thread's server address( ]; U/ ?+ B' g- ~8 h0 \
thread:get(name) - get the value of a global in the thread's env3 ]5 o% \9 T4 L4 `* w" W2 S0 R$ {
thread:set(name, value) - set the value of a global in the thread's env
4 }4 P# A' [1 hthread:stop() - stop the thread
# U! K: Y9 a7 u) V* W$ f% n. B
+ M# o4 q6 w$ Y+ K, F/ G0 j; d, V3 S5 p0 b* o, ?
运行阶段
! B- Z# F/ f& i, ?, Z' Bfunction init(args)  --由测试线程调用,只会在进入运行阶段时,调用一次。支持从启动wrk的命令中,获取命令行参数;
6 J# c6 N6 L% ?/ |9 Y; @+ Lfunction delay()  --在每次发送request之前调用,如果需要delay,那么delay相应时间;
9 [. B0 h9 |+ Z( r( L/ I6 H; xfunction request()  --用来生成请求;每一次请求都会调用该方法,所以注意不要在该方法中做耗时的操作;+ H' ~- R% z* I0 i0 r
function response(status, headers, body)  --在每次收到一个响应时调用;为提升性能,如果没有定义该方法,那么wrk不会解析headers和body;
8 m* v8 \5 O+ ?, D3 D1 \2 H 1 m& u  n, S9 o8 N  v" e, R
0 F" k# N" v2 R" ^( N
结束阶段
6 N+ `% K& o4 i) f2 a+ b4 Xfunction done(summary, latency, requests)  --在整个测试过程中只会调用一次,可从参数给定的对象中,获取压测结果,生成定制化的测试报告。
* G5 [$ e3 _9 Q8 z  r9 X- D   
  ]3 c1 g. D" F2 k* k) O) C. Y! V. w# c. C# n: b: ?
  2、自定义脚本中可访问的变量和方法:/ |* E3 R$ E# S# P

4 `1 T8 J; x; N- R% _0 A( d" o  变量:wrk
6 w% V+ l, L, F8 O5 m  I" y! C4 _9 `% U/ k+ J5 ?
复制代码' [5 s9 g$ S6 I
wrk = {; V( w+ ~6 r" ^4 t* R) p9 T6 ~
    scheme  = "http",
. Y$ m: L; w" F    host    = "localhost",
- {3 m' H" Q4 ?5 A$ `/ Q) p( J    port    = nil,; z3 l0 q; I. D/ r
    method  = "GET",
  ~5 E' [' u4 ]1 x3 K1 z5 v    path    = "/",1 M; h( f' ]* U; v# r' q5 R
    headers = {},- K  O: `7 u' L! w- I, n
    body    = nil,
2 l! ]1 d; S% A3 a2 L6 M- L& o$ i* F    thread  = <userdata>,5 W: V5 R$ }4 d3 I
  }
' C1 @6 K! r0 R% N4 @0 C" w3 g复制代码! I) |( o6 y$ P! h

1 x0 @7 X! D! p( M  N) ?5 P: n0 _5 x( f0 s
  方法:wrk.fomat wrk.lookup wrk.connect                  / @! ^* l5 j6 G  ]7 o6 U" e

) }6 Q0 O3 r- r% O5 Pfunction wrk.format(method, path, headers, body)  --根据参数和全局变量wrk,生成一个HTTP rquest string。
3 P4 W: W# l: |! \/ D8 Tfunction wrk.lookup(host, service)  --给定host和service(port/well known service name),返回所有可用的服务器地址信息。# |' o2 c" K8 D* h9 ]0 e# y
function wrk.connect(addr)  --测试与给定的服务器地址信息是否可以成功创建连接
% {8 q  T  D  m# q: F6 i, Q5 G' U 4 G6 F" b8 }3 x
3 l& Z8 R: i) I4 Q% `9 {1 U
3、lua脚本压测实例
! j9 k6 S2 R' J  w: D$ ~
2 ~/ S) k9 Z3 ~  压测命令:wrk -t8 -c200 -d30s --latency  -s test.lua http://www.bing.com
9 Z* ]8 x) O) T; l9 i$ Q
% v3 E0 z7 q- f9 T- |& r) c  test.lua是用lua写的压测脚本,如下是压测脚本的实例:
" `: V; G0 h; Z& J1 Y0 t1 C2 Q3 w7 `/ {0 p/ W/ b# E  Y. L
  使用post方法压测
5 m; _' N  ]+ M& r+ q) k0 u! X1 o( s9 Y7 N) n
复制代码
9 y& e6 e( ]8 w. O! O' Zwrk.method = "POST"1 Z2 v# l8 C9 Y) U
wrk.headers["S-COOKIE2"]="a=2&b=Input&c=10.0&d=20191114***", T4 {3 a: e# Q
wrk.body = "recent_seven=20191127_32;20191128_111", ~1 ^# C, i4 j' q+ a/ s' Y
wrk.headers["Host"]="api.shouji.**.com"
* P3 y& @4 J; S
/ g+ ]6 k- \3 ?) _# nfunction response(status,headers,body)% {- B$ v1 s9 d* G: f
        if status ~= 200 then --将服务器返回状态码不是200的请求结果打印出来' v9 D0 _6 R' y# a" V2 F
                print(body)+ @) W5 ]+ V9 X/ G! B( u: z- Q
        --      wrk.thread:stop()
4 Z$ q0 Q/ ^% k: b' W        end
& J& f4 d: h* b. K0 W' Q8 Q1 s) mend$ J: S$ k- O% Z2 g
复制代码# b( t6 Y& k( H2 C0 ^
3 M. n; Q2 @7 h" b4 {; z! E

5 n( H: u: k3 }3 g0 c# B4 w& Z8 n7 Q7 M   发送json
8 @. i0 t5 K; ?' P3 y
0 ]: j* v$ c+ E. `* u/ _: z复制代码
" b, D4 ^( p' }/ krequest = function()9 k0 h0 w! ?! g" q2 k& V: _7 c
    local headers = { }
% G& O% B  M0 t    headers['Content-Type'] = "application/json". _0 ]; S$ w* x  V: r9 f) z" U% G
    body = {3 Y9 s! t- x5 K0 K. O- h7 s
        mobile={"1533899828"},
3 P! A8 R$ d* w+ K        params={code=math.random(1000,9999)}& U, O* i/ ^9 P' {# @
    }
$ ^' n2 E5 H: m1 X3 w' F3 L6 R  Q    local cjson = require("cjson")$ d( G7 I$ {( Y" `, o
    body_str = cjson.encode(body)
/ d3 z9 ?: J# M- \- j8 p" r    return wrk.format('POST', nil, headers, body_str)
) ?. K( I5 m; s: u2 N/ S4 I3 uend
- h% G6 w/ w( k& f复制代码
4 \1 N. F% u* ]$ \# ~4 r- ~
/ i( z+ V" ~, i* u& `! K
, s% C1 H! {% a# _wrk读取文件,实现随机header-cookie
: q. ^' x6 m, }6 ]- G1 s; B% e! _4 N6 s; T8 ~5 v
复制代码5 X4 `# j" c) F0 E5 [: @3 c+ P
idArr = {}
; J  S3 ]4 `6 U0 Q' nfalg = 03 M& @4 R, @+ _1 n( g3 P
wrk.method = "POST"
% D2 T5 {, u" F2 V2 x% }  Qwrk.body = "a=1"* @6 g* G! L# J
function init(args)
3 c$ ~8 g% K7 O        for line in io.lines("integral/cookies.txt") do
  F5 l" |7 P* E- _% L                print(line)
' W% W; P" K# {/ I                idArr[falg] = line8 W, L+ K* R: ]) s
                falg = falg+14 K" _3 s. `3 n! z% l- F
        end
$ z4 X% N7 @6 M  [        falg = 0
9 o1 `, _0 f0 m' Y: S; C4 p( b. Fend
3 G' x8 Q4 {6 |% A6 A" G
5 I. d( e1 L* J& z% x--wrk.method = "POST"2 Y' F  r* {. i; k" f
--wrk.body = "a=1"! q0 h5 L; h* ~* |4 D4 ?5 U  M3 g3 k
--wrk.path = "/v1/points/reading"
0 P9 Y) B0 g* m$ u' P6 B  {! J
* k# d6 d! _7 i* ^- Urequest = function()
/ l" R. R( P5 h& Y$ j/ y        parms = idArr[math.random(0,4)] --随机传递文件中的参数3 [# x* c2 h4 O" K" l
        --parms = idArr[falg%(table.getn(idArr)+1)] 循环传递文件中的参数7 v6 q* A( [3 J& P; p1 V& j2 y+ G5 q
        wrk.headers["S-COOKIE2"] = parms
! S9 P- L' s, w- ^6 c. S        falg = falg+1
4 \) J3 U6 |% |# `9 E        return wrk.format()& v- g! U% |% t0 S; \
end
  E+ M5 j( S; P: N' c- D复制代码
. T. e% ]6 E* B3 R) }6 E
4 t- O. Y% ?- A+ D# s& |
7 k3 A% e1 g  `( A5 B' V  wrk创建数组并初始化,拼接随机参数" i) t7 d) K& |1 `* B
: l9 |* k+ y7 v
复制代码4 w$ T; _: D" D+ [" B6 W
idArr = {};, W/ v" l9 D+ t0 y* d6 L
function init(args)
% ?  j; e( Z& P' D) Q3 M        idArr[1] = "1";
( I4 g6 S8 @/ m9 x        idArr[2] = "2";3 N$ }( [! I& T* i0 I
        idArr[3] = "3";
' L8 o5 J7 m7 {/ F" G$ T4 |/ ^: t, K$ v        idArr[4] = "4";8 C4 W$ E  o# H6 h! K
end& S/ G+ [2 ~- Q  o8 S9 @- V* F

' t- h% p" W  w7 R. I2 @4 t3 brequest = function()/ |/ L9 p( a: }. c# r
        parms = idArr[math.random(1,4)]
- D+ N  Q$ C& g8 L4 L- v6 m        path = "/v1/points/reading?id="..parms
; i$ i8 r! U& J, t* W  a        return wrk.format("GET",path)
4 c/ n" z$ d0 R5 c' Kend
' l. C) q. P, r9 D2 Z  j复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-6-12 04:40 , Processed in 0.014503 second(s), 21 queries .

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

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