易陆发现互联网技术论坛

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

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

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

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

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

x

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

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

基础使用! q1 {7 x6 A  C& v8 D8 u3 h
使用类 Unix 环境,在 CentOs 或 MacOs 上进行测试

wrk 开源 GitHub 地址: https://github.com/wg/wrk  l5 i$ b3 P8 |- ~  ~' ]
通过 git clone 的形式下载 源码包,进入目录下,执行 make ,然后开始编译安装,等待一会即可完成。

wrk 使用参数说明
1 {: p+ C( ?& p) f9 `-c, --connections:  总的连接数(每个线程处理的连接数=总连接数/线程数)
) e! N0 N* j9 ~3 G. ?. r-d, --duration:        测试的持续时间,如2s(2second),2m(2minute),2h(hour)
) j/ L3 L9 X5 C% f+ @+ G-t, --threads:         需要执行的线程总数
' |: a/ `4 x1 ]0 m; |-s, --script:          执行Lua脚本,这里写lua脚本的路径和名称,后面会给出案例! D2 ?0 C6 {7 P7 F4 [
-H, --header:      需要添加的头信息,注意header的语法,举例,-H “token: abcdef”,说明一下,token,冒号,空格,abcdefg(不要忘记空格,否则会报错的)。% F' O7 N* s/ f1 K
--latency:     显示延迟统计信息. }  g: p6 O3 v
--timeout:     超时的时间
3 F# w. I$ s/ T例子  y" L# H) T% t. H/ S
wrk -t12 -c400 -d30s http://127.0.0.1:8080/index.html. [$ m7 T: d$ P9 r* u4 ]
该请求意思为: 使用 wrk 使用12个线程,400个连接,请求 url 30s

压测结束后的结果:& [+ f# ?, r. J+ ^9 Q5 T
Running 30s test @ http://127.0.0.1:8080/index.html+ C% t- z) n& L& u
  12 threads and 400 connections
5 j5 _2 Z* X# j7 w  Thread Stats   Avg      Stdev     Max   +/- Stdev' x: S, I9 _+ u$ W% N
    Latency   635.91us    0.89ms  12.92ms   93.69%
2 e( G. {" V# q/ O5 J7 S1 [    Req/Sec    56.20k     8.07k   62.00k    86.54%
4 x: M8 w, z! m% x% j* W  22464657 requests in 30.00s, 17.76GB read0 G& V5 U( x1 S2 C9 m
Requests/sec: 748868.539 D6 }& V5 B, i7 ^
Transfer/sec:    606.33MB* e% J& g. ^$ Z2 `/ u0 P
返回结果说明:

Latency:响应时间Req/Sec:每个线程每秒钟的执行的连接数" J1 L! m+ [' {9 V" e) a
Avg:平均
! J  b  k$ X& U0 U9 v8 R5 sMax:最大" b, t  c8 q) l  Y% {8 s8 I4 A. j
Stdev:标准差+/- Stdev: 正负一个标准差占比
# P% _6 _( C5 n3 c1 hRequests/sec:每秒请求数(也就是QPS),这是一项压力测试的性能指标,通过这个参数可以看出吞吐量
6 j* V% y! P2 a6 z8 ?Latency Distribution,如果命名中添加了0 a$ n* C; v$ H( ^
latency就会出现相关信息
; {! f9 z8 |9 {, ?) A, o实战' }, A: ^% V& Z- \! h0 k
使用 wrk 对鉴权的接口进行调用压测。由于是鉴权的接口,需要根据密钥和时间戳动态的生成 secret 然后对后端进行请求,才能通过验证。这里我们引入 lua 脚本
3 g8 D2 z( ~# j5 M: a由于 wrk 工具里面 自带 luaJit ,所以我们不用下载。但是需要 md5 的模块,所以需要使用 luarocks 来管理和下载 lua 模块和包。

安装Luarocks 包管理工具
* {4 n4 l$ m4 t& [. VLuaRocks 是 Lua 模块的包管理器。它允许您将 Lua 模块创建并安装为自包含包(称为 rocks )。您可以在 Unix 和 Windows 上下载和安装 LuaRocks。官网:https://luarocks.org/

通过 curl 下载) q, J% G9 _& G4 ^. W
curl -o luarockt-3.0.3.tar.gz http://luarocks.github.io/luarocks/releases/luarocks-3.0.3.tar.gz
- d5 L: q8 W+ D/ a0 H- |8 c- C解压 luarockt-3.0.3.tar.gz后,进入目录下 指定到 wrk 里 LuaJit 的目录进行 configure

//这里指定你自己的 `wrk` 路径6 k* V6 @8 i6 E( H
./configure --with-lua=../wrk/obj
2 Y% k2 v3 X: M' c# y编译安装
) j. t, P- `; ?2 S- H! hmake install
: W6 m$ k$ A* K" c8 n! G2 T6 q3 ~通过 Luarocks 安装 md5 模块
: K( V0 r: s8 z5 N# W" X$ X9 |luarocks install md5

开始请求
5 A5 v+ [) M5 S我们需要像 url http://127.0.0.1:9000 网关进行 POST 请求,该网关会对请求进行鉴权和验证,并判断请求的实效性。所以我们需要在请求时动态改变请求参数,因此需要结合 Lua 脚本。

Lua 脚本 helloDemo.lua& ?. N1 S- q# G) v, z
md5=require("md5")
6 I' t+ h; C% w# C; C9 w- q5 W-- md5加密,拼接请求对象4 j" K4 K" A( T
function buildJson(json)- v7 U+ T, e, C6 U. t2 n% U! d
  local apiKey = "abcdefg1234567"! T5 g( q- }. {" X: q, X
  local password = "qwerxxxx"- q/ x  x% U7 C- z
  local timestamp = os.time() .. "000", B0 \8 ~) u" ]7 M' J6 Y1 ^9 \
  local secret = md5.sumhexa(apiKey .. timestamp ..  password)0 m. C' ?7 ?- |- s
  local body = json .. "×tamp=" .. timestamp .. "&secret=" .. secret0 n: s6 V$ c2 C, R6 m
  ; M- D! Z6 T9 }3 J) b
  return body
# u! B* Y' Q/ h3 R! R3 Q# j5 Uend

wrk.method = "POST"
0 Y# C4 r8 h" ]3 zwrk.body = buildJson("serviceName=com.github.dapeng.service.HelloService&version=1.0.0&methodName=sayHello¶meter={\"body\": {\"request\": {\"bizTag\": \"order\", \"step\": 100}}}")
& F) A6 {% Z( J3 p, kwrk.headers["Content-Type"] = "application/x-www-form-urlencoded"
) m3 w* d, b$ w4 W- w8 F& i6 g请求脚本

#!/usr/bin/env bash( }1 R0 l0 \( L$ R* u8 e6 d7 T
time1=`date +%s`/ t0 l) e" A0 h7 D" ~
echo "开始时间 `date +%Y%m%d%H%S`"3 K; F- D( S" R# C- c
# wrk 安装目录 -s 后指定上面写好的lua脚本" F/ l; L1 u+ O# j  d* k
~/ideaspace/dapeng/benchmark/wrk/wrk -t4 -c400 --timeout 5s -d 60s -s lua/$1.lua --latency 'http://127.0.0.1:9000/api/e1bfd762321e409cee4ac0b6e841963c'7 q. e/ V- t" P" V
time2=`date +%s`
0 _0 p1 y9 z3 Q9 N  q* GuseTime=$[time2 - time1]
' g  i2 O0 V4 H1 y/ ~- [7 lecho "结束时间 `date +%Y%m%d%H%S`"
) ~) S# L1 h5 I& i+ Q: [1 f/ Uecho "总共花费 $useTime s"5 @/ t- T" D) h
执行脚本

sh start-wrk.sh helloDemo
, j) u9 P: g. m$ j通过上面方式,我们就可以开始请求已鉴权的接口

总结, p( ~8 \3 z, o  f( q$ T# |0 p: D, x
wrk 是一款高性能的 http 请求压测工具,它使用了 Epoll 模型,使所有请求都是异步非阻塞模式的,因此对系统资源能够应用到极致,可以压满 cpu。
+ l  [' ~# R9 K0 }5 O/ Y4 Lwrk 可以落站使用 Lua 脚本。该特性可以使我们通过 脚本动态的改变请求参数,对请求压测提供的多样性的选择和定制。

后续. R6 s) y# A2 O, s
1. 去除 CO$ I- x  J8 x% Y  S6 V- ~, z
关于 wrk 测试延迟分布不准确的问题,涉及到 Coordinated Omission 的原因,可 Google
! z% h' B- C- o* |6 m在 src/wrk.c# E9 U" q$ x) t# L
将下面部分代码注释:; V7 G5 x* C4 b. G5 W5 J% l( S
//  if(complete / cfg.connections > 0) {
5 `+ V5 o3 u# @9 X6 J  O% d//       int64_t interval = runtime_us / ( complete / cfg.connections);
# G  i& J6 t" T, w6 l9 a% ], b//       stats_correct(statistics,latency,interval);1 y% d3 H" P8 n/ I. j
关于 wrk 测试延迟分布不准确的问题,涉及到 Coordinated Omission 的原因,可 Google,也可以参考 wrk2


) u' o1 C" q( c1 o( o. ]: i: S! E7 Q+ {/ T0 |
[color=rgba(0, 0, 0, 0.75)]wrk入门总结# k, ~, n* p3 i5 `9 W

" t" s" x/ b& ]' `% s一、功能介绍:

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

二、安装过程:

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


/ x/ b7 I: X# f4 e# ^5 m
  • make编译过程中问题解决:

    1. -bash: make: command not found

    [root@XXX wrk2-master]# make-bash: make: command not found
    # Y" N2 I$ b( J  ~5 M

0 W( J$ ?- x/ Z. d( `

  系统无法使用make,make install,一般出现== -bash: make: command not found ==的提示,是因为安装系统的时候使用的是最小化安装,缺少make、vim等常用命令。
; D: k& T5 u3 ~  d  直接安装make即可解决问题:

[root@XXX wrk2-master]#yum -y install gcc automake autoconf libtool make
. F, Z: M* {9 W1 a  J
5 v( \$ z. a( i0 _3 m' Q. B8 ^, x

  安装g++:

[root@XXX wrk2-master]#yum install gcc gcc-c++& g2 p5 [' B! D0 u" @
8 p4 g) b2 b0 I( Z

2. src/wrk.h:11:25: fatal error: openssl/ssl.h: No such file or directory
+ G% F7 O5 V: \8 O2 ]https://img-blog.csdnimg.cn/2020052220505566.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NjY2NzeTk5,size_16,color_FFFFFF,t_70! i7 I$ O0 @$ I/ E7 U9 a4 O5 H: T
  问题在于:系统中缺少openssl库,安装即可

[root@XXX wrk2-master]# yum install openssl-devel  或者[root@XXX wrk2-master]# yum install libssl-dev. u* R7 S* R+ z: i  N, O/ j" L

: F8 z4 m$ j6 m1 f三、wrk 初步使用
  • 基本用法:

    Basic Usage: wrk <options> <url>

    Options:                                                -c, --connections <N>  Connections to keep open' g9 E- z  S, S
     # HTTP连接数,如1k,1M,1G,    -d, --duration  <T>  Duration of test  8 r( u  h* r& C
    # 测试持续时间,如 2s 2m 2h              -t, --threads <N>  Number of threads to use  
6 C2 d: g; B3 o: m( G- s6 E; Y( S( `    # 开启的线程数                                                           -s, --script   <S>  Load Lua script file 5 V3 }8 H1 Q; v' a
  # 进阶功能,使用 lua 脚本    -H, --header   <H>  Add header to request  ; S  W1 B9 p7 Y1 a6 a* {
  # 添加请求头                    & f4 k! R. s8 b- I/ V$ x* H% M
# 打印详细延迟统计    -L  --latency    Print latency statistics       -U  --u_latency  Print uncorrceted latency statistics                     ==, s+ y8 _$ b. c; ^
# 设置请求超时时间,大于该时间的请求将被记录==          --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)   
. P4 n- R' T) u4 F4 ?#工作速率(吞吐量)即每个线程每秒钟完成的请求数                           in requests/sec (total)                               [Required Parameter]# p( y7 j2 ]+ t5 G

; [/ r- L0 s' V" U; R/ s
  • 使用方法–readme; A  n, D4 F% J) F/ s" Q1 E% a
[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个请求延迟标识,延迟百分比

4 _# F4 F# I2 a# `/ ^四 测试场景
  • 测试HTTP协议网络的性能[root@XXX scripts]# wrk -t2 -c1000 -d15 -R1000 --latency https://www.baidu.com/
    4 C+ t, p# k, F; E
    • 1# T4 [3 \7 n4 H
    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

3 ]9 ]/ I/ {5 o9 b2 c& Z. Y

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

  • 测试当前服务的最大QPS

      进入安装目录,运行

    6 x& f) R9 M7 ~( G! _& q( E
[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

* e7 T/ n; g3 f" P  H

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

  • 使用Lua脚本个性化wrk压测
    ! d2 g" \& N( A! T

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

 楼主| 发表于 2020-11-11 17:00:14 | 显示全部楼层
软件简介  L: d* S6 w3 F
wrk 是一个比较先进的 HTTP 压力测试工具,当在单个多核 CPU 上运行时,能够产生大量负载。它结合了多线程设计和可扩展的事件通知系统,例如 epoll 和 kqueue。
( e# `  t  f+ z& F. L% y( C" z
! B$ k3 c* U  w, U可选的 LuaJIT 脚本可以执行 HTTP 请求生成,响应处理和自定义报告。
3 ^, H4 [2 K; W+ d0 ~
! J+ A0 W' c/ u+ B3 j" U测试方法:
( [7 Z6 u$ ^: ^9 e$ E; E  W; d: a
wrk -t8 -c400 -r10m http://localhost:8080/index.html; D4 O) ?2 o5 P5 x# V# H
输出结果:+ M/ U; ?2 A( t4 E( U
3 `! J' i* p% c( G. C
  Making 10000000 requests to http://localhost:8080/index.html
2 u$ V+ J( C2 R- F& o' h    8 threads and 400 connections/ @1 \+ X4 g7 ^! p' a; b
    Thread Stats   Avg      Stdev     Max   +/- Stdev0 t: I$ i# [4 T$ u( R
      Latency   439.75us  350.49us   7.60ms   92.88%! ~8 g- `  r) z. M4 a
      Req/Sec    61.13k     8.26k   72.00k    87.54%2 y9 w- `0 @+ p/ m, i
    10000088 requests in 19.87s, 3.42GB read
2 s6 `7 `% I  e0 [* n9 ^( `  Requests/sec: 503396.23
9 F/ l6 i9 u- o  Transfer/sec:    176.16MB
7 f8 Q: L' d* f3 |9 [( L8 u
 楼主| 发表于 2020-11-11 17:00:15 | 显示全部楼层
一、简介
" I) c9 v$ B8 A7 x  {
$ y" A% o* d0 w; ?  wrk 是一款针对 Http 协议的基准测试工具,它能够在单机多核 CPU 的条件下,使用系统自带的高性能 I/O 机制,如 epoll,kqueue 等,通过多线程和事件模式,对目标机器产生大量的负载。: Y4 R8 B3 o7 [  A

8 z. L; y. ~( y. y6 `* dwrk是开源的, 代码在 github 上:https://github.com/wg/wrk( R$ M4 N: {) o9 [
. u7 `( \! }+ C$ L+ o: v2 Z
安装:https://www.cnblogs.com/savorboard/p/wrk.html
9 n) B: P2 p4 j' Q  M) F8 |% j' W. m
0 K  y" D; \/ @+ z4 l8 U
3 {$ m4 \4 \+ h- o7 C3 B! M
优势:
* b. q5 |* T- s6 b9 c" B1 O# A* R1 h5 G5 K, \1 e
轻量级性能测试工具
- S' v4 q/ H1 ?9 c9 M安装简单3 p: N, B* G0 f- t8 Y5 S8 y# F. R
学习曲线基本为0,几分钟就学会使用了% H3 B2 B+ m$ q5 @8 }9 B
基于系统自带的高性能I/O机制,如epoll,kqueue,利用异步的事件驱动框架,通过很少的线程就可以压出很大的并发量,例如几万、几十万,这是很多性能测试工具无法做到的。
' W( a' i) p( c8 r5 j) V0 I3 N1 k劣势:: y& {* F9 g7 M

: D5 I+ |5 y, f% Q. {/ Lwrk 目前仅支持单机压测,后续也不太可能支持多机器对目标机压测,因为它本身的定位,并不是用来取代 JMeter, LoadRunner 等专业的测试工具。) n' \$ S. i4 ?9 u5 x4 L. k7 M/ S
! h% |6 V' Q8 ~% x

# A- H" r3 |$ c% z 二、格式及用法
2 Q- ]  l/ ^6 ~: {4 o! ]# V
' d( {' ]" _% [: l. G- @$ `复制代码+ o3 ~; C9 C4 U& o
Usage: wrk <options> <url>                           
2 l* Y2 X  c- }- g! \3 x9 B/ Y6 L1 x3 |* t( P& Y
  Options:                                          
5 Y: [8 w1 l% H    -c, --connections <N>  Connections to keep open  . ?6 c% B- ?6 E7 S: _1 `
    -d, --duration    <T>  Duration of test            n* f" s0 O4 A: w- ~; z3 g" R
    -t, --threads     <N>  Number of threads to use  
3 |5 L3 k! v4 G7 K, o2 B+ m5 C                                                     
1 {6 i6 i# W9 X) f8 G& z    -s, --script      <S>  Load Lua script file      6 c6 o3 t0 \+ ^  v: o
    -H, --header      <H>  Add header to request     7 M! p' _, V% x! R4 y
        --latency          Print latency statistics  . M. {6 |  Z+ J- i
        --timeout     <T>  Socket/request timeout    ; ], I; Y+ Q3 {- j- B! W
    -v, --version          Print version details     
# x5 S8 b7 f' A; \0 g" t# K                                                0 V9 C; j# }! d9 B. B  \- V( U
  Numeric arguments may include a SI unit (1k, 1M, 1G)9 R; X  R  v2 A
  Time arguments may include a time unit (2s, 2m, 2h)2 q& J5 X/ g9 |  Y% W
复制代码
$ x" f0 @0 {* M
2 P2 J. R' c- ^$ a  H: p: {- \- `, v
翻译成中文:/ o$ h0 J# z3 X6 r+ K7 L1 `3 C0 h

' `0 x: a4 y$ s复制代码0 p$ u; W; t8 _7 U' A2 `- L
使用方法: wrk <选项> <被测HTTP服务的URL>                           ! k  I0 I! L' \" B' w* q  q! U

7 d- {+ z) E5 A0 ?% o8 g' Z  Options:                                          
& v+ O: @% M6 n  l- F+ a! y+ Q% s    -c, --connections <N>  跟服务器建立并保持的TCP连接数量
: e4 Y& J# R0 C8 [  H- m    -d, --duration    <T>  压测时间         
, R0 e3 W4 J/ R/ Y. k" r    -t, --threads     <N>  使用多少个线程进行压测,压测时,是有一个主线程来控制我们设置的n个子线程间调度  7 |* O1 N/ L( N" l4 e
                                                    9 H! @: W- Y( w2 P/ W# G6 F! X
    -s, --script      <S>  指定Lua脚本路径      
% t, @  f* `/ I& B& w2 ^    -H, --header      <H>  为每一个HTTP请求添加HTTP头     
. E1 R% ]+ M- t' \% |& _' y  U        --latency          在压测结束后,打印延迟统计信息  # F% {5 K- H' j! b- W
        --timeout     <T>  超时时间   
5 t% N- Q+ f. ?8 `    -v, --version          打印正在使用的wrk的详细版本信                                             
- c# ~2 L6 s. R) C  T4 Q$ F% Q1 \4 ]
, U5 j2 i4 o; w6 j# S) e  <N>代表数字参数,支持国际单位 (1k, 1M, 1G)# h2 R+ ^6 r7 X$ b
  <T>代表时间参数,支持时间单位 (2s, 2m, 2h)- j; W& s, u4 `: W6 b' R
复制代码
1 E7 f& _6 P/ \5 E5 Q' w' y 2 W, v6 s" z7 P2 V# I
% x" ~4 X) ]6 {& G* K7 w
; R9 G  w8 S7 R7 ?9 l
7 Q5 b6 Y" B9 h* i0 v
三、简单压测及结果分析
, Q, F0 g; t( K7 o7 T2 |2 O
9 I& r4 f* n* s0 l做一个简单的压测,分析下结果:
, h$ |: {& }9 @7 q; W1 w1 m
3 P; R! u" Y- Q# }: A+ swrk -t8 -c200 -d30s --latency  http://www.bing.com
8 k$ S" c7 `: }% |. v7 q4 n 1 H* w1 w' R1 V" U

* Y6 Q$ U8 J  E3 h) e. V8 g% q输出:: x- q# h: J; {+ a# u5 Y/ w( ?
9 H! V/ V1 Z, [. S6 G4 I" M
复制代码
7 z7 J+ @! H0 N/ `& N" HRunning 30s test @ http://www.bing.com, a+ `: H+ C1 c0 t& ]. C
& `, D' A" v# A% [  Y
  8 threads and 200 connections
' a# |  O/ j  R1 a( w% t; P3 s
2 u9 S9 {" ^" B0 ?1 c  Thread Stats   Avg      Stdev     Max   +/- Stdev
$ c7 [+ a' R5 P    Latency    46.67ms  215.38ms   1.67s    95.59%
+ O! {; E2 g; G$ S    Req/Sec     7.91k     1.15k   10.26k    70.77%
: n- W! b) g& E
3 Y" T- [1 l% T! h( k7 z6 g0 ]  Latency Distribution
  O: X% _4 J8 ^& ]! L3 n4 Z     50%    2.93ms
* I, j, i) G, h2 [# a+ K5 s- _     75%    3.78ms9 x/ p0 c; r( D2 N
     90%    4.73ms3 Z" O/ R) C: g
     99%    1.35s7 o1 N' r% H  u4 \
  1790465 requests in 30.01s, 684.08MB read
4 ?0 {: T- V! E/ PRequests/sec:  59658.29% O5 }6 X1 v  k$ b. l. @, I0 M
Transfer/sec:     22.79MB: W/ A, o5 i$ S6 G( i8 g
复制代码
# q$ F) ?1 C% C9 Q7 |以上是使用8个线程200个连接,对bing首页进行了30秒的压测,并要求在压测结果中输出响应延迟信息。
2 L$ I/ E# j( V  K  t8 A% ^% d* D# B. ~: G" B; A
以下是解释压测结果:
7 S4 q% F# q( D4 _6 a: g& e" O/ u
' R+ G& u0 N! X: A/ O! Y复制代码
- ^: ]" B. }* K3 }- _Running 30s test @ http://www.bing.com (压测时间30s)
, v" U, u7 }1 ^/ W; s5 n! J8 r9 J1 m* `" f
  8 threads and 200 connections (共8个测试线程,200个连接)- O% j% ~6 p& P0 c& C
2 V& F3 W* s+ I' X8 m( e  A) D
  Thread Stats   Avg      Stdev     Max   +/- Stdev
8 U1 H) U; x, _3 c              (平均值) (标准差)(最大值)(正负一个标准差所占比例)
! b% t4 M* q7 W" K    Latency    46.67ms  215.38ms   1.67s    95.59%) F6 b* V2 [  ]% I1 D
    (延迟)& b( j& l& k: [& s. G
    Req/Sec     7.91k     1.15k   10.26k    70.77%  `8 `4 v- ]2 m) d# y0 g
    (处理中的请求数)
* u% O( a4 |  x; {* B- a" O2 t5 [
  Latency Distribution (延迟分布)
, B* G. T% W' w$ M     50%    2.93ms
# @: l- r( V1 x# t# Y     75%    3.78ms- ]9 l5 U: k6 N2 g9 q1 H  O
     90%    4.73ms  \7 h" o; J  Y% G8 j5 ^
     99%    1.35s (99分位的延迟:%99的请求在1.35s以内)
: l; b9 F/ q) p4 c" S* o& j  1790465 requests in 30.01s, 684.08MB read (30.01秒内共处理完成了1790465个请求,读取了684.08MB数据)4 |& b8 w0 c3 S  N2 y$ j7 B
Requests/sec:  59658.29 (平均每秒处理完成59658.29个请求)5 l8 D; d+ s: r. x7 t/ X8 q
Transfer/sec:     22.79MB (平均每秒读取数据22.79MB)9 r# o8 z6 H7 w1 q  g
复制代码
6 N$ o; X1 T) ?5 t) O* ~7 k8 q/ r( E
8 g4 Q! b1 Z1 G4 T4 Z. k
7 _5 T' }9 b& p& n4 o) C
$ Q$ e( O1 y# Z
5 C8 @- o9 S. N1 ~  J" [) ~6 w0 O4 h四、使用lua脚本进行压测2 \% Y4 A, x. ]- R6 [4 a' R7 w
+ l% ?4 x: l( Q& V8 a
  lua脚本是一种轻量小巧的脚本语言,用标准c语言编写,并以源代码形式开放,其设计目的是为了嵌入应用程序中,从而为程序提供灵活的扩展和定制功能。wrk工具嵌入了lua脚本语言,因此,在自定义压测场景时,可在wrk目录下使用lua定制压测场景。2 X4 V; w9 C% N3 p, ?2 |  D3 F

2 E- P& h+ _, L  1、lua声明周期, {; U1 Q- G# v1 X- C
' N( c9 @' q  B8 @. J
    共有三个阶段,启动阶段,运行阶段,结束阶段。wrk支持在这三个阶段对压测进行个性化。   9 h: F! n# ^+ y2 u/ A# D, V  b

  |1 }5 d3 X+ c" h* Z6 u启动阶段! i+ ^5 Z; I1 S1 n; s, a; z
function setup(thread)) C, ?/ T; A. [1 Z1 u5 m
- R4 i7 e+ Y$ y
$ I( C2 P: y9 h5 V& |; m
在脚本文件中实现setup方法,wrk就会在测试线程已经初始化但还没有启动的时候调用该方法。wrk会为每一个测试线程调用一次setup方法,并传入代表测试线程的对象thread作为参数。setup方法中可操作该thread对象,获取信息、存储信息、甚至关闭该线程。
4 S3 R8 h$ _/ L  G& C  A% p0 P# u! c7 g1 _4 f0 s! l6 {8 z
thread.addr - get or set the thread's server address
5 D# L' \1 k& E; r2 T7 k& Zthread:get(name) - get the value of a global in the thread's env7 b% s/ Z! v! p! p6 g
thread:set(name, value) - set the value of a global in the thread's env
! {& B4 y9 t0 W% f5 U6 b/ }; n. Wthread:stop() - stop the thread' I( Y& y2 |' w( Z4 R( {

7 O4 W! E( @! O. k5 ~4 Z6 }& ^: W2 x% v5 ]
运行阶段: O1 V/ o% o2 _2 C
function init(args)  --由测试线程调用,只会在进入运行阶段时,调用一次。支持从启动wrk的命令中,获取命令行参数;' s% L/ v* E9 G3 Y. w
function delay()  --在每次发送request之前调用,如果需要delay,那么delay相应时间;3 p4 w& K; W- p$ s6 H
function request()  --用来生成请求;每一次请求都会调用该方法,所以注意不要在该方法中做耗时的操作;1 O, N3 V) `$ A; ?9 U, `0 U; C7 s" Y- W
function response(status, headers, body)  --在每次收到一个响应时调用;为提升性能,如果没有定义该方法,那么wrk不会解析headers和body;2 ^/ R/ `2 _6 Y8 }6 r! @" O% h4 V: J
2 U, S# v$ O6 J3 A6 G0 w/ ]
3 Q1 g# H/ q% C
结束阶段" @, m( H0 w$ {  {
function done(summary, latency, requests)  --在整个测试过程中只会调用一次,可从参数给定的对象中,获取压测结果,生成定制化的测试报告。
: Z3 }5 c1 e( x( C3 e   
' ~9 `/ N! `2 ~# y# f# Z* k0 y9 x2 Q, t3 O' b
  2、自定义脚本中可访问的变量和方法:6 [/ W- e: L: p& ^

! h) b$ c$ O: p7 f8 A  变量:wrk$ w; e0 q) U( }! _
% P/ X; m3 M4 y9 k  M- o+ u2 f
复制代码
4 M$ G. _1 X4 \* Z) \; Ewrk = {
0 {, c2 g' v6 F3 m    scheme  = "http",  L  [. \3 q. `  D
    host    = "localhost",: M& R3 r- v4 `& j' ^# \
    port    = nil,' m, f/ C" p. [9 k1 t, s. U
    method  = "GET",
4 ^8 J+ k( x% g* M! R4 p/ E    path    = "/",- z: d* n  X+ U5 |7 Z1 l; ?
    headers = {},
% T6 E: S" c6 A3 `% ]' f; f2 y    body    = nil,# m1 X/ a1 I& m/ b0 L
    thread  = <userdata>,
# l( |+ f! N/ ]. B0 D: m* i  }6 y# I; _8 ~6 u' ]: K* B
复制代码
! o( X" C) r" v/ h" v0 k7 C  ^7 ^$ d
( W& J3 n' l7 p# w1 C: M$ w. Z7 o8 b3 U3 {
  方法:wrk.fomat wrk.lookup wrk.connect                  
1 \" X5 S! Z0 F, g* i
# ?3 g6 ~) A, m' u6 Jfunction wrk.format(method, path, headers, body)  --根据参数和全局变量wrk,生成一个HTTP rquest string。, I! m* ~- f- F% J8 L
function wrk.lookup(host, service)  --给定host和service(port/well known service name),返回所有可用的服务器地址信息。
7 l* _6 K* g. V6 m- |: d7 dfunction wrk.connect(addr)  --测试与给定的服务器地址信息是否可以成功创建连接
' J. k% F/ D5 @) k1 S! | 8 k8 K4 M! u- i3 Q% I$ C' l9 l& w0 a
3 Q' h  q0 b( U; ~2 b) N
3、lua脚本压测实例
6 k- y! t$ O6 }$ k: Z+ K( v& E8 F- g( s7 U3 u
  压测命令:wrk -t8 -c200 -d30s --latency  -s test.lua http://www.bing.com4 e7 p1 q; I% {% c2 `# G# {: T
# S9 p3 o! H( K1 c$ F' K
  test.lua是用lua写的压测脚本,如下是压测脚本的实例:
6 I  |$ l4 F; G" m
9 p2 ]0 |% b9 c& t  使用post方法压测6 ]/ b7 _$ ^7 ^% M$ i% s
2 K8 o. E% M: }( ?1 \& }
复制代码
5 E" B1 D& M' {1 \$ _( \& e: t9 lwrk.method = "POST"; A& Y3 c" u, C$ B
wrk.headers["S-COOKIE2"]="a=2&b=Input&c=10.0&d=20191114***"
6 ]4 B7 N3 t  s, F% bwrk.body = "recent_seven=20191127_32;20191128_111"" C% Z5 g2 P7 r8 S) `2 @9 L% l
wrk.headers["Host"]="api.shouji.**.com"
% d1 c( H% l, k  K& ^& ]
9 Q7 l# j, Y1 G" E7 H$ Bfunction response(status,headers,body)( U5 F$ X; E5 S8 `7 R
        if status ~= 200 then --将服务器返回状态码不是200的请求结果打印出来+ `' O& v6 u  p6 S, Y
                print(body)  `! `4 J( e7 R1 Z5 J7 Q
        --      wrk.thread:stop()4 B( |$ E: R; T* p
        end  t: E; Y1 O3 D0 K- Y) E. Y
end3 J7 |+ W& m8 {' Q* \6 f! O2 m
复制代码
- v: _' @' u3 Z0 C # k- w- ^* ~* ~5 x! U
( T) Z1 O" m. m! Z7 T
   发送json
4 u$ U/ s# V& N( F& T8 B& v/ [- p5 H$ j5 Z' L3 W
复制代码2 x, R! U! [* Q1 M) r( T5 W" ^
request = function()
1 R+ `5 s1 m( R    local headers = { }9 e: G! O' x0 p. h
    headers['Content-Type'] = "application/json": N0 w8 L. e: |2 N$ G
    body = {
( M, x4 B! |) r2 [: y  X& D        mobile={"1533899828"},
5 J" |, j7 L- N8 J$ p        params={code=math.random(1000,9999)}8 C. c# F! }3 O# C4 h
    }
8 S1 K# F" q5 z8 ]: B    local cjson = require("cjson")" m" W0 R! Q0 i  Y
    body_str = cjson.encode(body)
2 L  U: c! @2 g- f0 k7 O    return wrk.format('POST', nil, headers, body_str)4 H  j+ e% ~0 B8 [. K( \: F
end6 M+ J8 g/ ]4 o5 j, R! f
复制代码, u/ K2 G! g, D. F- ^4 w1 P' n5 n
. R, N+ d! }# W  y9 J: S8 Z$ W7 N
& \; M8 {" z5 s3 O1 c( e0 x" ^
wrk读取文件,实现随机header-cookie
/ a. g/ ^/ k5 W' c% q
. j( N  q& C$ ]复制代码
- w: X- [9 d6 p/ }idArr = {}$ Y& o" [% Q) O% _1 a8 L/ O  f6 {
falg = 0
" ]+ X( l5 ?- l) Xwrk.method = "POST"
2 ~0 W% j: ~8 @" U% o" cwrk.body = "a=1"
$ X8 j3 T3 c6 m4 {function init(args)
, ^3 x! b9 P# s1 H        for line in io.lines("integral/cookies.txt") do
: W, k* R: |# l. k4 a8 a! h' Q                print(line)
, N$ d" n7 y7 e, V1 |                idArr[falg] = line
% E$ S/ j4 }% v+ |8 M1 {$ n* l                falg = falg+13 |# k, V! w& \7 O1 o4 i
        end
7 S0 f- e5 s4 A& b        falg = 0! O5 Z8 B0 b& m6 W% Y) C  H
end! |# d3 M7 W* f+ O
' {# ^* h6 J+ q' Q/ ^
--wrk.method = "POST"
7 \& g3 L. ^, E0 f# P$ ^3 L0 @--wrk.body = "a=1"
4 A# t. z. c* B: C3 g  \1 H--wrk.path = "/v1/points/reading"! |6 Z! i$ G  r  o, ?
3 p' i# |. u' Y- b" i9 D. X2 a. ?/ c
request = function()
/ S, E: k) ?2 \2 T; i& q        parms = idArr[math.random(0,4)] --随机传递文件中的参数- Z! n% `- X' j3 l1 K% B7 ^8 p
        --parms = idArr[falg%(table.getn(idArr)+1)] 循环传递文件中的参数0 m- Z7 X. `. U/ j7 r  E  X  y
        wrk.headers["S-COOKIE2"] = parms* E" x$ U8 J. K% T# |2 W
        falg = falg+1
: U# ~! M& M. M: I1 C& {8 D        return wrk.format()
" H$ t( O& _6 `) L( x. q" ]end
" T: M/ ]0 b* b( l) d复制代码
* O. A9 l$ o% u9 k) [, p
' l1 K0 V5 E* w6 `4 ]$ @1 c7 t: |' {. h3 J7 g
  wrk创建数组并初始化,拼接随机参数
5 A' z7 I0 Z8 `+ K. D: C5 N6 A; U8 v1 p7 n7 y6 n
复制代码* X5 E% h+ |* ~3 N+ N0 t
idArr = {};3 Y  G, T' f* b* g$ Z7 D1 v$ U
function init(args)' o( t5 y$ ]; c8 E
        idArr[1] = "1";
. X" b. n3 x& Y; G        idArr[2] = "2";9 l+ |* U% U" ?8 l$ C3 R" h
        idArr[3] = "3";
/ q6 R/ G/ @6 h( c6 A( d" S        idArr[4] = "4";
; l( x& X+ \7 |) e1 m+ H$ ~2 v& fend# p$ m0 y: t3 c4 _/ f' R

  d7 R. i0 e4 Jrequest = function()0 U7 l9 ^7 ^% O( d' p
        parms = idArr[math.random(1,4)]
; G) ]+ t' x) P+ Q5 g4 D        path = "/v1/points/reading?id="..parms
: B0 l+ g4 O( A# o" E4 q        return wrk.format("GET",path)( e& [$ x0 V/ y' d+ W6 K
end1 y! u' z4 {8 N
复制代码
您需要登录后才可以回帖 登录 | 开始注册

本版积分规则

关闭

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

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

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

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

Powered by Discuz! X3.4 Licensed

© 2012-2025 Discuz! Team.

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