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

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

[复制链接]

1

主题

0

回帖

12

积分

管理员

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

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

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

基础使用; u9 G. k  L- [: s
使用类 Unix 环境,在 CentOs 或 MacOs 上进行测试

wrk 开源 GitHub 地址: https://github.com/wg/wrk5 h# @3 a/ U: ]6 u
通过 git clone 的形式下载 源码包,进入目录下,执行 make ,然后开始编译安装,等待一会即可完成。

wrk 使用参数说明/ u; o% {, T# k7 A1 R& G
-c, --connections:  总的连接数(每个线程处理的连接数=总连接数/线程数)
  d9 \2 Y  l& Z+ T% z5 ^-d, --duration:        测试的持续时间,如2s(2second),2m(2minute),2h(hour)) d0 j" i( _; r- |3 m7 z
-t, --threads:         需要执行的线程总数& y' R% f! W6 h( b" m0 i' K1 N  y
-s, --script:          执行Lua脚本,这里写lua脚本的路径和名称,后面会给出案例
7 d' ]+ v6 L- e% k-H, --header:      需要添加的头信息,注意header的语法,举例,-H “token: abcdef”,说明一下,token,冒号,空格,abcdefg(不要忘记空格,否则会报错的)。
; E2 \6 w: a# l* ]0 d" C5 C; F--latency:     显示延迟统计信息2 \% V( R6 o% u+ D- u2 G6 {
--timeout:     超时的时间
! j& B- u0 o4 }! J$ I9 S例子; K  T: O, C' x7 k% _2 c" c
wrk -t12 -c400 -d30s http://127.0.0.1:8080/index.html
+ u0 u5 U- F$ `$ D) s# j7 ?- x  o该请求意思为: 使用 wrk 使用12个线程,400个连接,请求 url 30s

压测结束后的结果:
* a" V  R9 L! r/ v* \Running 30s test @ http://127.0.0.1:8080/index.html7 r4 Y$ q5 n; _( Y
  12 threads and 400 connections
3 k3 A% l7 a8 j# W0 A5 B  Thread Stats   Avg      Stdev     Max   +/- Stdev$ f6 k/ D1 }% K8 v  |7 m% i
    Latency   635.91us    0.89ms  12.92ms   93.69%* I- v+ t& i8 B" l1 ^; c, A) G0 n' a; |
    Req/Sec    56.20k     8.07k   62.00k    86.54%
* U7 d1 c) N; X9 _9 H  22464657 requests in 30.00s, 17.76GB read
3 ]# d) V* u9 f, g+ p/ u% i* lRequests/sec: 748868.53
# {/ D2 R( h: B$ t, ?Transfer/sec:    606.33MB
1 ?* }6 ~9 j+ c) v返回结果说明:

Latency:响应时间Req/Sec:每个线程每秒钟的执行的连接数
4 Q- Z9 N( ]) V' ]$ t! R2 m$ LAvg:平均
: w% M+ a) c, wMax:最大+ w1 Y7 ^0 K& b" J& G% T, W
Stdev:标准差+/- Stdev: 正负一个标准差占比, H! X/ ?$ c& H4 t* O
Requests/sec:每秒请求数(也就是QPS),这是一项压力测试的性能指标,通过这个参数可以看出吞吐量
# k1 A% B* H' G! q. E2 E5 q" RLatency Distribution,如果命名中添加了. b$ B4 n. x+ \) y
latency就会出现相关信息# r/ y0 F. A$ o9 t: J7 P0 ~
实战/ H% U' u) u; E2 p
使用 wrk 对鉴权的接口进行调用压测。由于是鉴权的接口,需要根据密钥和时间戳动态的生成 secret 然后对后端进行请求,才能通过验证。这里我们引入 lua 脚本3 L$ X; D" C$ k5 l# d" D
由于 wrk 工具里面 自带 luaJit ,所以我们不用下载。但是需要 md5 的模块,所以需要使用 luarocks 来管理和下载 lua 模块和包。

安装Luarocks 包管理工具
5 l6 S5 f9 ]: I! h7 y5 N8 F; o2 qLuaRocks 是 Lua 模块的包管理器。它允许您将 Lua 模块创建并安装为自包含包(称为 rocks )。您可以在 Unix 和 Windows 上下载和安装 LuaRocks。官网:https://luarocks.org/

通过 curl 下载. Q& z# ]1 \  H' R- {, b
curl -o luarockt-3.0.3.tar.gz http://luarocks.github.io/luarocks/releases/luarocks-3.0.3.tar.gz
, Y6 o7 t/ n" H3 D6 }解压 luarockt-3.0.3.tar.gz后,进入目录下 指定到 wrk 里 LuaJit 的目录进行 configure

//这里指定你自己的 `wrk` 路径
1 v' g3 n/ g( ]" [/ B" |2 M' I./configure --with-lua=../wrk/obj( I& Z0 I8 z% C- m+ Z
编译安装& w8 {8 ~* u0 ^! c+ m0 a/ _, h7 O
make install* O* y7 f  j, I3 O* Y9 F* M; B
通过 Luarocks 安装 md5 模块
/ f# I  o3 k" Z( O4 zluarocks install md5

开始请求+ I5 n( b% z3 e8 i" [. v
我们需要像 url http://127.0.0.1:9000 网关进行 POST 请求,该网关会对请求进行鉴权和验证,并判断请求的实效性。所以我们需要在请求时动态改变请求参数,因此需要结合 Lua 脚本。

Lua 脚本 helloDemo.lua& b# ~, p0 X4 T% x( e% X
md5=require("md5")
& l8 X/ S% D; P3 Z-- md5加密,拼接请求对象3 e& X( `8 G  m" Y8 x
function buildJson(json)+ N2 e. s; ?" q9 O( \
  local apiKey = "abcdefg1234567"
. k5 |$ j9 H9 P  K2 c) F  local password = "qwerxxxx"
' J: o/ ^+ P0 T* F  local timestamp = os.time() .. "000"
. ?- A) `+ [8 _: {8 [2 O  local secret = md5.sumhexa(apiKey .. timestamp ..  password)
8 v$ H: m+ f* K  local body = json .. "×tamp=" .. timestamp .. "&secret=" .. secret5 T$ H4 Z# l+ H* L, W
  , M5 r1 y6 K; u) t4 M
  return body9 X$ U" y" c3 h. ?
end

wrk.method = "POST"! F; D! ~  `! \+ Z3 A1 _
wrk.body = buildJson("serviceName=com.github.dapeng.service.HelloService&version=1.0.0&methodName=sayHello¶meter={\"body\": {\"request\": {\"bizTag\": \"order\", \"step\": 100}}}")( q) A  O  ^. \2 f
wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"+ v5 u6 \) |9 {* X, j' x7 t( o+ d; d' O
请求脚本

#!/usr/bin/env bash& g: `0 ^& ?: B+ z( E" h
time1=`date +%s`1 q* W. r) G: j5 k
echo "开始时间 `date +%Y%m%d%H%S`"
( [- i4 d+ S. S' |9 U/ ?# wrk 安装目录 -s 后指定上面写好的lua脚本
/ ~( y& N' P  d8 @- i: P: S( ?~/ideaspace/dapeng/benchmark/wrk/wrk -t4 -c400 --timeout 5s -d 60s -s lua/$1.lua --latency 'http://127.0.0.1:9000/api/e1bfd762321e409cee4ac0b6e841963c'
6 _% I; C/ s  ntime2=`date +%s`5 [. d& ]4 |  Y: x2 k
useTime=$[time2 - time1]
/ ^- b# g9 |' L' e# j, p" Oecho "结束时间 `date +%Y%m%d%H%S`"; |- y4 u% E# G$ n7 S% ?& B+ U6 S
echo "总共花费 $useTime s"
( s: R( t) l! J. m执行脚本

sh start-wrk.sh helloDemo- q, I  z' f& f+ X8 T% n
通过上面方式,我们就可以开始请求已鉴权的接口

总结
/ o4 |) X! J$ y: m5 K- o' iwrk 是一款高性能的 http 请求压测工具,它使用了 Epoll 模型,使所有请求都是异步非阻塞模式的,因此对系统资源能够应用到极致,可以压满 cpu。
0 F9 T$ L/ m# M1 a7 z6 F- g8 Dwrk 可以落站使用 Lua 脚本。该特性可以使我们通过 脚本动态的改变请求参数,对请求压测提供的多样性的选择和定制。

后续
# K. x, W! n6 [! |8 O/ {1. 去除 CO' G8 x" \3 g" X0 N7 [
关于 wrk 测试延迟分布不准确的问题,涉及到 Coordinated Omission 的原因,可 Google
: `: y% d6 B6 P0 H, f/ b2 Y( {在 src/wrk.c1 o  s, k/ ?2 `* W
将下面部分代码注释:. t; N/ Q7 `. ~& T" n7 `5 n2 w
//  if(complete / cfg.connections > 0) {
7 D& R" z4 E6 _( u/ y! ^/ e0 C//       int64_t interval = runtime_us / ( complete / cfg.connections);
" `. {: n7 P. M& ?//       stats_correct(statistics,latency,interval);
3 @( Y$ v- c9 R. r6 i关于 wrk 测试延迟分布不准确的问题,涉及到 Coordinated Omission 的原因,可 Google,也可以参考 wrk2


9 p- S: u: S5 l1 s3 v1 a/ H* J% J
+ l) D9 t: _3 z1 H/ Q# N4 [' Uwrk入门总结
" h3 X# Q2 o/ f) \
7 \! n; g: n4 W( m% l7 G8 }3 r+ l一、功能介绍:

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

二、安装过程:

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


1 p% Q: P5 z. D$ H
  • make编译过程中问题解决:

    1. -bash: make: command not found

    [root@XXX wrk2-master]# make-bash: make: command not found; h2 f4 ~* V8 A" W. G' a

9 E; v8 w% \) ~- Z- ]7 o! Y

  系统无法使用make,make install,一般出现== -bash: make: command not found ==的提示,是因为安装系统的时候使用的是最小化安装,缺少make、vim等常用命令。
+ w& K# L! C0 Q! M' `- i2 |  直接安装make即可解决问题:

[root@XXX wrk2-master]#yum -y install gcc automake autoconf libtool make
& n& c0 j: M; @: i/ g7 e
: M8 B# b1 M" Q$ D5 B# c( }

  安装g++:

[root@XXX wrk2-master]#yum install gcc gcc-c++. h# P$ i5 I) B
) @+ ~4 O9 {: u5 ?

2. src/wrk.h:11:25: fatal error: openssl/ssl.h: No such file or directory6 |. X7 K" D! |" V. ^
https://img-blog.csdnimg.cn/2020052220505566.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NjY2NzeTk5,size_16,color_FFFFFF,t_705 p$ t0 l; b. t- @; [+ i
  问题在于:系统中缺少openssl库,安装即可

[root@XXX wrk2-master]# yum install openssl-devel  或者[root@XXX wrk2-master]# yum install libssl-dev
+ N" c2 f4 F6 t2 M, u1 F! ]/ x; M6 ~2 s8 ?9 O. ~8 f5 j6 Q  o
三、wrk 初步使用
  • 基本用法:

    Basic Usage: wrk <options> <url>

    Options:                                                -c, --connections <N>  Connections to keep open
    : o4 X) U0 d% Q5 K* f
     # HTTP连接数,如1k,1M,1G,    -d, --duration  <T>  Duration of test  
( z5 n- x* Z- N  g. f) Q4 k1 ?# x    # 测试持续时间,如 2s 2m 2h              -t, --threads <N>  Number of threads to use  
# ]) @" z! [; S; b) ^    # 开启的线程数                                                           -s, --script   <S>  Load Lua script file
- r5 [" J1 Y: M  # 进阶功能,使用 lua 脚本    -H, --header   <H>  Add header to request  
9 {( P" |8 A! Q* F6 X/ L- F) h  # 添加请求头                    
4 f+ r7 a& G6 T# m8 ?9 r5 V6 D # 打印详细延迟统计    -L  --latency    Print latency statistics       -U  --u_latency  Print uncorrceted latency statistics                     ==# \9 b- `; o7 l8 F
# 设置请求超时时间,大于该时间的请求将被记录==          --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)   
% {$ w# R3 e6 S& W* m$ R9 @$ x#工作速率(吞吐量)即每个线程每秒钟完成的请求数                           in requests/sec (total)                               [Required Parameter]- x! S/ {* y9 P9 z7 |7 J6 W* ]

+ Z) ^1 U* H' x4 F" M
  • 使用方法–readme" S- ?9 ^- E1 L5 U; V
[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个请求延迟标识,延迟百分比
2 A# S' p( t7 B% ?
四 测试场景
  • 测试HTTP协议网络的性能[root@XXX scripts]# wrk -t2 -c1000 -d15 -R1000 --latency https://www.baidu.com/( G7 i2 u3 M$ f% O2 {
    • 1
      + t1 r) z- ?6 W/ q
    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
# S! w8 R' A1 k# K9 l$ |

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

  • 测试当前服务的最大QPS

      进入安装目录,运行


    # v2 S) B2 t4 F3 H
[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

" W) f+ T" k' `& k

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

  • 使用Lua脚本个性化wrk压测& D- ^8 E* h% ]. C! E: G2 c2 W3 Y0 l

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

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
 楼主| 发表于 2020-11-11 17:00:14 | 显示全部楼层
软件简介
' E) q* o5 F; t% }3 \( v% c- pwrk 是一个比较先进的 HTTP 压力测试工具,当在单个多核 CPU 上运行时,能够产生大量负载。它结合了多线程设计和可扩展的事件通知系统,例如 epoll 和 kqueue。  g( I  p1 ^* G# E- \4 r, d3 u

. h( A2 v2 j1 B* x; D5 V; d4 V可选的 LuaJIT 脚本可以执行 HTTP 请求生成,响应处理和自定义报告。8 G0 V' J5 R$ C
* w  p# i, s' Z) F
测试方法:
- X+ k, S! R* K
2 Q- W4 O8 N: O: rwrk -t8 -c400 -r10m http://localhost:8080/index.html- e$ D* v* C$ A) _' X
输出结果:& y) ^7 D9 Q9 s4 i1 Y, j$ D$ D

: @: n: M7 Q5 m# _# d) c' b  Making 10000000 requests to http://localhost:8080/index.html6 ]3 W  L4 M  h& P8 k: a/ |: ^
    8 threads and 400 connections
" w* T9 H: w$ ~* E4 Y    Thread Stats   Avg      Stdev     Max   +/- Stdev
# j; _2 @% S0 ?/ |: b2 r      Latency   439.75us  350.49us   7.60ms   92.88%
" J! P) {* Y0 _+ M) ^8 }, M; N; X      Req/Sec    61.13k     8.26k   72.00k    87.54%. q1 c8 G9 v2 r* Y% _
    10000088 requests in 19.87s, 3.42GB read2 t. J7 p" U4 P
  Requests/sec: 503396.23; V- \/ G8 R5 q+ U0 M
  Transfer/sec:    176.16MB
& }: O: l3 C$ U

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
 楼主| 发表于 2020-11-11 17:00:15 | 显示全部楼层
一、简介: H2 n0 ^0 {* U0 d5 C$ R3 i
& w) e& Y- B8 Y1 M2 @$ k
  wrk 是一款针对 Http 协议的基准测试工具,它能够在单机多核 CPU 的条件下,使用系统自带的高性能 I/O 机制,如 epoll,kqueue 等,通过多线程和事件模式,对目标机器产生大量的负载。
% n, R, c! t! B1 P8 Z' ~
4 Q, L" u: B; \8 n( a! c9 _" awrk是开源的, 代码在 github 上:https://github.com/wg/wrk& b( _4 W' }3 U6 }5 B

0 Z2 l0 A4 Y# }6 y安装:https://www.cnblogs.com/savorboard/p/wrk.html! Q4 [3 i5 R+ i: f% ?: ]! y) h
! P1 C+ b+ i: w: _0 u3 d; m
- Z  f% a  E8 g0 d' N- \$ p3 ^

/ h0 u8 j0 r" [9 m. F- X优势:: N8 O. q* J" Q1 I

4 w* ^3 W; q2 l5 i+ m# H轻量级性能测试工具
! D* a  M4 Z* j% w安装简单
* W6 X6 @0 k) ^; |+ q9 u6 K学习曲线基本为0,几分钟就学会使用了) f2 V! X2 \' T* z. Y/ Y$ v( Z
基于系统自带的高性能I/O机制,如epoll,kqueue,利用异步的事件驱动框架,通过很少的线程就可以压出很大的并发量,例如几万、几十万,这是很多性能测试工具无法做到的。* t) t. o3 l; A, t* Q; c
劣势:
- A' z2 m* X: D% ?9 s0 @5 o: [3 X$ L8 T
& V4 [3 j8 S" {5 v% y7 K& fwrk 目前仅支持单机压测,后续也不太可能支持多机器对目标机压测,因为它本身的定位,并不是用来取代 JMeter, LoadRunner 等专业的测试工具。' k' U. N4 V, }, ?! ?9 S
* u! O! F# Q9 z" F; ?
  W2 G8 [; c3 D  [$ ?" k3 V
二、格式及用法& s! z( _5 x3 z% G

! n0 z% y) f& x" L% {, ~复制代码( n; n( L: m4 v7 u1 ~( s
Usage: wrk <options> <url>                           ' C6 E5 ~( r' `/ `: `( ?# ]% _

- a1 L! Q6 v; m7 U/ w# K  Options:                                          
  n2 G* l) Q1 @& p3 }  p    -c, --connections <N>  Connections to keep open  6 Q5 ^+ g4 ~. J9 P/ \6 Y
    -d, --duration    <T>  Duration of test         
: J) C% C/ `  z$ w3 K; F  S    -t, --threads     <N>  Number of threads to use  
1 P: D7 r: X$ R, \                                                     6 r% ~8 \& z* _2 T- ]
    -s, --script      <S>  Load Lua script file      # f# _6 w" K8 M2 ]! y. `
    -H, --header      <H>  Add header to request     
/ d1 \* d! _- D# |8 Q+ A        --latency          Print latency statistics  
' N0 S7 Y/ U" e# N+ D  a        --timeout     <T>  Socket/request timeout   
2 z- Y0 x/ m* J- F7 W    -v, --version          Print version details     
% [9 o% l" E: W4 A                                                
7 a& N! P! K8 ~& N% e( \. x* e  Numeric arguments may include a SI unit (1k, 1M, 1G)
5 f' Y  j0 p# L- K! |  E  Time arguments may include a time unit (2s, 2m, 2h)
: l$ c. E2 O1 b. u: o复制代码
( E$ j" P# g7 r, l3 p* @$ ^ 3 ]" i. p9 g. r4 j! o
% k, o( F, E+ k2 v; M
翻译成中文:
! t9 t2 g/ j! x, T- S8 Z! ?# T* _9 q; x* j* n
复制代码
/ _) z3 V- H. ]) J2 l使用方法: wrk <选项> <被测HTTP服务的URL>                           + Q/ }9 Y1 Y7 e% t2 x3 g

/ G% T8 @4 Q, ~3 s  Options:                                           3 o- x4 C* |* q% i, z+ O  j% w
    -c, --connections <N>  跟服务器建立并保持的TCP连接数量
# h( ?6 Z3 a% g8 |+ ]2 ?. F    -d, --duration    <T>  压测时间         
& o3 a+ C0 r4 K: M' B    -t, --threads     <N>  使用多少个线程进行压测,压测时,是有一个主线程来控制我们设置的n个子线程间调度  2 y6 _, S4 _( M
                                                    : K* F. b, ~: L" k, m: v9 p: T
    -s, --script      <S>  指定Lua脚本路径      6 p: i4 B1 A0 A' c' j! Q
    -H, --header      <H>  为每一个HTTP请求添加HTTP头     . z+ I+ C$ g: P& v( }/ D
        --latency          在压测结束后,打印延迟统计信息  
# J- B( H$ @5 D        --timeout     <T>  超时时间    , T( o, o/ s" D" r
    -v, --version          打印正在使用的wrk的详细版本信                                              - N" [8 `( c# w9 q9 [+ B

" J# {3 c! r1 E- M  <N>代表数字参数,支持国际单位 (1k, 1M, 1G)
  N0 S' r; u3 h2 F4 f  <T>代表时间参数,支持时间单位 (2s, 2m, 2h), ]% e# H9 n. |2 N; d; k
复制代码
+ e! J# s! p% u 9 i. w3 R, ]' C7 H% `, M& a/ S3 u
2 w6 P& Y+ t% S1 v$ z  j

8 C- p; M1 @3 U, N7 @  v
3 U2 G5 O' h) n; N9 G三、简单压测及结果分析# Z" m% }6 E1 H+ y9 \
( n8 n; G' @& [" J
做一个简单的压测,分析下结果:* l9 V' w, b' x8 ]8 _) Y4 b

7 y2 O/ x6 [/ I0 L7 F; ~. lwrk -t8 -c200 -d30s --latency  http://www.bing.com% A0 V! ?9 L- v- L! B

' h8 @# n, r0 e" l8 Q, P$ G4 q# W
: @1 g+ r0 T9 J6 |" {: @! ^输出:
8 |: s/ H; A6 ?5 l0 m) y. f3 h7 }2 o2 f8 z& n
复制代码
% Q# S, W1 O) C, o0 [/ ]Running 30s test @ http://www.bing.com. i/ t- Q5 D8 U" R% s
4 C& F; A" B/ x; W
  8 threads and 200 connections
+ ?& R& ^! t; {, @  I
5 n: Q7 k% h! I) m0 m  Thread Stats   Avg      Stdev     Max   +/- Stdev
$ |) |4 Q6 e; S& t; r    Latency    46.67ms  215.38ms   1.67s    95.59%8 L" Y# _9 N2 y9 b! N( A$ G
    Req/Sec     7.91k     1.15k   10.26k    70.77%* k& e" x' C4 k0 o! k6 t2 ?( W
5 b, }; N* X& Z- Z
  Latency Distribution6 S6 n& A7 y( b* j# c& E4 `
     50%    2.93ms
! b' c8 c0 @1 k0 Q     75%    3.78ms
$ m8 B* ^) m/ u0 o8 F, Q     90%    4.73ms
$ U; S! @) P6 {6 r7 R8 f, a( j     99%    1.35s
1 d  S, T4 k$ D. u! }; \  1790465 requests in 30.01s, 684.08MB read
# v; u) q$ r; Q- t( L+ U1 |Requests/sec:  59658.29' u) s0 v/ {5 w! \! U' I2 v
Transfer/sec:     22.79MB2 t) R, O/ d. V6 a) _! u
复制代码
3 `: c9 v( k' I以上是使用8个线程200个连接,对bing首页进行了30秒的压测,并要求在压测结果中输出响应延迟信息。
0 T7 C$ d7 L# M' M
: @# k# }3 S9 U( k4 O以下是解释压测结果:
# ?+ L6 e0 \0 A  h3 F9 V7 a# J7 s& O
复制代码
7 A; |" x0 U! TRunning 30s test @ http://www.bing.com (压测时间30s)$ m& ~7 s' t) R5 l5 \& ^. M$ r
4 b: n: H& X( [3 r( |2 B- _% Q$ G
  8 threads and 200 connections (共8个测试线程,200个连接)
0 I+ v; `; S9 }3 }1 p( E0 w0 ^- v
  Thread Stats   Avg      Stdev     Max   +/- Stdev% ]# [# B" {0 T5 y2 L
              (平均值) (标准差)(最大值)(正负一个标准差所占比例)2 J& U8 h' U( ?5 g3 w4 p
    Latency    46.67ms  215.38ms   1.67s    95.59%: v/ J. }  d0 a
    (延迟)
9 N% X: h$ ^: G* G' T; F4 X    Req/Sec     7.91k     1.15k   10.26k    70.77%- k5 a. r  r  B; J3 B, D. H
    (处理中的请求数)0 Y" k- ]: ?0 f. k' n0 D2 t
+ |6 x, x* A1 a; s- A
  Latency Distribution (延迟分布)
; S8 u. A# E( C& g) @6 [     50%    2.93ms
/ s8 W9 ]1 Z9 c4 R7 \$ ^     75%    3.78ms& Y* U. ^# i1 G4 D# c+ P
     90%    4.73ms
& A1 G  B6 m* l2 z% Y     99%    1.35s (99分位的延迟:%99的请求在1.35s以内)+ l7 C6 Z$ I& Y- j: F8 V, O
  1790465 requests in 30.01s, 684.08MB read (30.01秒内共处理完成了1790465个请求,读取了684.08MB数据)4 e3 {7 y( W( {' w$ w
Requests/sec:  59658.29 (平均每秒处理完成59658.29个请求)
3 O% l( e4 z0 E1 X+ LTransfer/sec:     22.79MB (平均每秒读取数据22.79MB)
% ]5 Z8 [9 v' h3 p/ x/ @复制代码- E+ n) z) t% B' F* S4 H
( x) ]$ r; ]8 ]. H9 i

8 u2 ^/ f& j, U( P/ W7 J/ U
; {' \8 ^0 g- m% U; m; T/ [( H+ v! C* L, ?! N( y" a: ?5 u
四、使用lua脚本进行压测
$ Z, S! J7 q) N4 T6 ^: }( E  y. `( q6 Q+ O& ^! E
  lua脚本是一种轻量小巧的脚本语言,用标准c语言编写,并以源代码形式开放,其设计目的是为了嵌入应用程序中,从而为程序提供灵活的扩展和定制功能。wrk工具嵌入了lua脚本语言,因此,在自定义压测场景时,可在wrk目录下使用lua定制压测场景。
& b* v3 B2 s% ~" b, b2 ]$ L0 Q; A7 X  n1 T7 e& v2 v" T
  1、lua声明周期
5 f. j+ ~6 T' ~- s% q: V; ~, y* T% L, T" k+ M6 C- O+ x, K4 r9 ~
    共有三个阶段,启动阶段,运行阶段,结束阶段。wrk支持在这三个阶段对压测进行个性化。   " I2 `7 ?' T, @1 x, _; ~3 T: _# P

0 p/ W+ v1 X5 P3 _1 c启动阶段# z4 {7 {5 C" \, A7 ~
function setup(thread); V: {7 q8 [1 @( g
1 J; Z; H8 I. U+ P" B, \0 r
! [( T2 C/ W( ~+ {
在脚本文件中实现setup方法,wrk就会在测试线程已经初始化但还没有启动的时候调用该方法。wrk会为每一个测试线程调用一次setup方法,并传入代表测试线程的对象thread作为参数。setup方法中可操作该thread对象,获取信息、存储信息、甚至关闭该线程。6 F- E$ s( b/ o! O

9 ~% ]7 @, u% l( Z$ b8 Nthread.addr - get or set the thread's server address) F( X# k0 g7 M% V' q, B9 H
thread:get(name) - get the value of a global in the thread's env
' h  h" j. }! E5 j/ F/ }$ C: jthread:set(name, value) - set the value of a global in the thread's env) R: o# n. t$ W' m0 B( C
thread:stop() - stop the thread$ i9 c! ^8 ^% \

; x% \4 Y- B1 N2 ?
/ c) T3 {* d+ L7 G# x; {8 g1 t- _3 B运行阶段9 a3 d, v' V, k2 ~3 R" ]
function init(args)  --由测试线程调用,只会在进入运行阶段时,调用一次。支持从启动wrk的命令中,获取命令行参数;
) [* _& R2 ^4 i  b7 hfunction delay()  --在每次发送request之前调用,如果需要delay,那么delay相应时间;, H& x, [( f$ J* i9 Z$ ]
function request()  --用来生成请求;每一次请求都会调用该方法,所以注意不要在该方法中做耗时的操作;: w* F, I  ^6 Y* j! N
function response(status, headers, body)  --在每次收到一个响应时调用;为提升性能,如果没有定义该方法,那么wrk不会解析headers和body;
1 Y/ d9 Q9 @3 }+ y! B8 B$ f4 O 4 f3 i! [3 c' v% W& i
  s, `/ }8 J  ^
结束阶段
) \( n& T: x+ c  Y; g, {* f+ Vfunction done(summary, latency, requests)  --在整个测试过程中只会调用一次,可从参数给定的对象中,获取压测结果,生成定制化的测试报告。) d0 i1 e( X; n& a: N
  0 ~. V- H6 i" H2 t9 G/ R/ p

, e4 E4 _0 t2 _9 \  2、自定义脚本中可访问的变量和方法:
8 Y/ l7 b# m1 e( l6 S
# v' ~3 q) l# T6 V0 Y  变量:wrk- m2 q6 i* E2 C: w2 [6 f

1 L1 V5 C& ~1 ^$ i; ?6 P1 Q复制代码0 G, C  ]0 h% [+ c- v" b4 X
wrk = {
- k9 N' U% h3 V2 L$ L5 o9 [    scheme  = "http",
6 Q* m* Y7 G' ]( Q    host    = "localhost",* h' N( e5 `0 P5 L
    port    = nil,
" U1 o9 f! E6 g    method  = "GET",
" {7 |' V' G' R$ ]; L. p    path    = "/",3 x- T# G/ a+ [% b
    headers = {},
/ N" v: j% `6 a8 `6 O    body    = nil,% f8 ^0 z! k/ o. u( f
    thread  = <userdata>,
( m, @# y1 q9 |. H  |4 o: D  }0 J$ c" H( S( g7 D8 k: g
复制代码
2 I) H  e2 s4 _+ p. A; K
$ p- t0 D, h8 w8 h
6 p3 B: L& w0 M- u( O7 r# Z  方法:wrk.fomat wrk.lookup wrk.connect                  
9 k' \! d' k" a* a; W
& q5 q' f7 s+ J& C0 E0 u9 Dfunction wrk.format(method, path, headers, body)  --根据参数和全局变量wrk,生成一个HTTP rquest string。
6 d) l3 Z% k! W" E- W. Ufunction wrk.lookup(host, service)  --给定host和service(port/well known service name),返回所有可用的服务器地址信息。9 T5 V* _7 R5 ]1 M8 p+ ?# _
function wrk.connect(addr)  --测试与给定的服务器地址信息是否可以成功创建连接
" N3 J6 \9 ?  e: q9 P3 P & F: p# K$ l! ?* I2 X7 m

  \6 G2 n) F3 a9 M0 W$ q4 x3、lua脚本压测实例( M( l+ P1 H9 v% A4 y
9 M% ?5 `6 d) i
  压测命令:wrk -t8 -c200 -d30s --latency  -s test.lua http://www.bing.com2 y' e2 x1 d- ?, M# L

* P+ i. \  m( T  test.lua是用lua写的压测脚本,如下是压测脚本的实例:# ^, W' D' [) F% E& j5 X
! M* o5 O0 x+ a6 _" D5 u: G
  使用post方法压测% o. q9 l7 Y! r# r

5 `5 p! l7 S# p2 v7 L复制代码
* I! r9 q  a) u. q7 @& _6 W! ^wrk.method = "POST"6 J* h! E. K8 T/ t  V' h
wrk.headers["S-COOKIE2"]="a=2&b=Input&c=10.0&d=20191114***"0 F% |2 c3 z1 [# c
wrk.body = "recent_seven=20191127_32;20191128_111". T) u" b' p6 d7 z' y  v
wrk.headers["Host"]="api.shouji.**.com"6 A  A8 p4 W4 ~. x
" a' z( Q" M; Q% a; [
function response(status,headers,body)2 O. T, H! b6 F/ L0 v
        if status ~= 200 then --将服务器返回状态码不是200的请求结果打印出来
5 q$ h5 l# u9 n* N                print(body)$ z# `# Z. }" F$ @  }: w' O
        --      wrk.thread:stop()8 ?! h/ U& q' q6 T9 ?; O( F+ K
        end
% M* U  q: v2 a% `0 r, o- e# j% Pend. n1 y' o2 v4 u: N
复制代码
+ J: q) e4 _' Y; T1 S, {1 ~0 A 5 c  C* P( x" {  S4 `
. V1 f9 `; G4 R2 X) ], s2 t6 R
   发送json$ t/ ~5 ]* g( F" e

$ [' S+ u' Z% M" d& J; s复制代码
, Q0 N) x. k0 lrequest = function(), l) u1 J: [6 ^4 r
    local headers = { }1 Q7 f( \0 L! a
    headers['Content-Type'] = "application/json"1 ]# Q6 Q( v" v# ?# l. t: I
    body = {0 Q- R" C  x8 F! M+ P
        mobile={"1533899828"},9 U6 q: T: h$ `4 O2 x
        params={code=math.random(1000,9999)}) O* Q; [/ i9 \/ n/ ^3 [
    }
# ]! a9 \' o% E2 P    local cjson = require("cjson")
, A/ x% C& I7 j: s4 ^" S4 W+ o    body_str = cjson.encode(body)
1 G- C6 L( P% c' [) Z6 @+ e    return wrk.format('POST', nil, headers, body_str)
2 D- F1 u$ I1 J9 h+ cend
0 X. N8 b6 ~! K  V/ S4 x8 Z复制代码
% ]: j- F4 C+ q; p' _/ X' G 2 x" r' M8 Z7 O! n, E% X$ q" J  E

4 U8 y# R! U7 H7 M. @$ |$ v7 e8 Uwrk读取文件,实现随机header-cookie
1 `- T3 I, a4 H' U( o
3 R6 I5 U& x! i; |" k6 o9 \复制代码
, u; N7 D4 W$ E+ ]4 Y" eidArr = {}
/ a; [( p" n0 ^% m, }8 e+ c6 Cfalg = 0
. V5 C2 u1 G) j. l! twrk.method = "POST"1 h; I  L' h  @0 e
wrk.body = "a=1"
/ Z  h: m5 |( Lfunction init(args)5 P1 O8 T4 D) H1 p5 Z! q# L
        for line in io.lines("integral/cookies.txt") do1 u' g6 u  d" b$ M+ w6 \" T
                print(line)
) f, y  q8 x$ H* k# u& l  g                idArr[falg] = line' N9 P' a7 f& j+ j. x  ~
                falg = falg+1, d" c# m& X% H* g
        end3 V0 @: ^: q. z9 l" o7 i
        falg = 02 T% v1 a% m9 _8 d1 k# ?
end5 T8 z4 V& {: u4 Y
' {  p+ S& E3 \2 y: w* a
--wrk.method = "POST"0 Y' ]4 g: ^1 s7 c/ ^
--wrk.body = "a=1"
) j4 q; m) i4 X: s" h5 U1 }--wrk.path = "/v1/points/reading"
" }& c6 h( c: x/ X0 C- a
6 M' O5 p7 C9 N8 _$ U6 hrequest = function(). u7 h; ?! a  M* n9 P- U+ w0 K
        parms = idArr[math.random(0,4)] --随机传递文件中的参数7 B% M8 p. B3 A  U
        --parms = idArr[falg%(table.getn(idArr)+1)] 循环传递文件中的参数; _- k5 Z6 d  g
        wrk.headers["S-COOKIE2"] = parms
: V0 z& h5 E; Q+ j        falg = falg+1
% c/ e2 f/ O0 e( U. V* {        return wrk.format()/ f7 J$ l4 |1 K/ O6 X- P3 O/ s! d& b
end
9 D& L0 i8 r  b5 K' ?) X, o复制代码
( S" s' s1 X' S3 V# N ! M5 E; A$ g$ K4 i, }0 J
' C" j, v5 m0 c3 W7 {( ], [0 e. e
  wrk创建数组并初始化,拼接随机参数1 J# e# i' s- X8 [; k

2 D1 j1 h' ~; J复制代码
1 u7 Z& k7 R6 P: l% yidArr = {};! x% K8 e+ m6 E' L- B) L4 I4 [- ^& h/ h
function init(args)2 w8 L; w0 w' }" |# k* c
        idArr[1] = "1";3 H8 |- Q% j" E- S6 z
        idArr[2] = "2";
$ k7 `4 U0 T4 `        idArr[3] = "3";. N1 V* _" w0 d* d5 m
        idArr[4] = "4";0 \5 I  x, w5 W( X4 J+ r2 q
end! j% n, N0 a. f

0 @. E2 e* {8 A; ]! Y0 [4 w6 yrequest = function()8 {0 c4 |) a9 l9 x; p
        parms = idArr[math.random(1,4)]
$ w! j8 w' g. j# v6 `        path = "/v1/points/reading?id="..parms
8 j7 d, B, v" c0 U1 N/ z* u        return wrk.format("GET",path). _. f# ?/ F( P8 [, ]! Z; U8 H
end  S4 {+ S2 b& s$ u9 g& V
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-6-12 04:37 , Processed in 0.017616 second(s), 22 queries .

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

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