centos7中使用wrk进行压力测试

wrk是一款开源的性能测试工具 ,简单易用,没有Load Runner那么复杂,他和 apache benchmark(ab)同属于性能测试工具,但是比 ab 功能更加强大,并且可以支持lua脚本来创建复杂的测试场景。

wrk 的一个很好的特性就是能用很少的线程压出很大的并发量, 原因是它使用了一些操作系统特定的高性能 I/O 机制, 比如 select, epoll, kqueue 等。 其实它是复用了 redis 的 ae 异步事件驱动框架. 确切的说 ae 事件驱动框架并不是 redis 发明的, 它来自于 Tcl的解释器 jim, 这个小巧高效的框架, 因为被 redis 采用,而更多的被大家所熟知。

1.wrk安装

centos7中默认安装了lua5.1.4,但如果要装lua-cjson插件,需要源码重新安装下lua,否则安装lua-cjson比较麻烦,各种报错。

//lua5.1.4需要安装 readline-devel才能编译成功
yum install -y readline-devel

//源码安装lua5.1.4
curl -R -O http://www.lua.org/ftp/lua-5.1.4.tar.gz
tar zxf lua-5.1.4.tar.gz
cd lua-5.1.4
make linux test
make install

//覆盖旧的版本
rm -rf /usr/bin/lua
ln -s /usr/local/bin/lua /usr/bin

//查看lua
lua -v

//安装lua-cjson插件,通过 <a href="https://luarocks.org/#quick-start" data-mce-href="https://luarocks.org/#quick-start">luarocks</a> 进行安装
//yum源中有luarocks,不过我通过yum安装,使用报错,所以我采用官网源码进行编译安装
wget https://luarocks.org/releases/luarocks-3.9.1.tar.gz
tar zxpf luarocks-3.9.1.tar.gz
cd luarocks-3.9.1
./configure && make && sudo make install
//然后安装lua-cjson,luarocks是个很方便的lua包管理工具,使用实用
luarocks install lua-cjson

//查看是否安装成功,在终端打开lua测试一下

//安装wrk
yum -y install gcc automake autoconf libtool make
yum install gcc++
yum install openssl-devel
yum install -y git
git clone https://github.com/wg/wrk.git wrk
cd wrk
make
# 把生成的 wrk 移到一个 PATH 目录下面, 比如
cp wrk /usr/bin
安装完成

 

2.wrk使用

 

使用方法: wrk <选项> <被测HTTP服务的URL>
  Options:
    -c, --connections <N>  跟服务器建立并保持的 TCP 连接数量
    -d, --duration    <T>  压测时间
    -t, --threads     <N>  使用多少个线程进行压测
    -s, --script      <S>  指定 Lua 脚本路径
    -H, --header      <H>  为每一个 HTTP 请求添加 HTTP 头
        --latency          在压测结束后,打印响应时间统计信息
        --timeout     <T>  超时时间
    -v, --version          打印正在使用的 wrk 的详细版本信息
 
  <N>代表数字参数,支持国际单位 (1k, 1M, 1G)
  <T>代表时间参数,支持时间单位 (2s, 2m, 2h)

来一个简单的压力测试,结果如下:

8个线程100个链接持续30秒

wrk -t8 -c200 -d30s --latency  "https://www.baidu.com"

输出:

Running 30s test @ https://www.baidu.com
  8 threads and 200 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    45.65ms    9.79ms 526.92ms   98.69%
    Req/Sec   439.30    161.90   636.00     81.19%
  Latency Distribution
     50%   43.98ms
     75%   47.10ms
     90%   48.04ms
     99%   57.90ms
  29400 requests in 30.10s, 294.28MB read
  Socket errors: connect 0, read 34743, write 0, timeout 0
Requests/sec:    976.74
Transfer/sec:      9.78MB

参数解释:

Latency:响应时间
Req/Sec:每个线程每秒钟的完成的请求数
Avg:平均
Max:最大
Stdev:标准差
+/- Stdev: 正负一个标准差占比

 

使用lua脚本压测

在上面的压测中, 每次发送的请求都是一样的都是GET请求,很多时候我们压测的请求体是每个请求都不一样, 这时候就要写lua脚本来压测
使用 POST 方法压测

创建test.lua文件,增加如下内容:
--请求方式为POST
wrk.method = "POST"
--请求body内容
wrk.body   = "a=1110&b=112"
--请求头格式表单格式
wrk.headers["Content-Type"] = "application/x-www-form-urlencoded" 

使用创建的lua脚本进行测试

wrk -t2 -d30s -c1k -s test.lua http://abc.com

每个 request 请求的参数都不一样


--更高级的,可以深入lua学习,读取数据文件来进行
request = function()
   uid = math.random(1, 10000000)
   path = "/test?uid=" .. uid
   return wrk.format(nil, path)
end

解释一下 wrk.format 这个函数

wrk.format 这个函数的作用,根据参数和全局变量 wrk 生成一个 http 请求
函数签名: function wrk.format(method, path, headers, body)
method:http方法,比如GET/POST等
path: url上的路径(含函数)
headers: http header
body: http body

每个线程先登录然后压测

token = nil
path  = "/authenticate"
request = function()
   return wrk.format("GET", path)
end
response = function(status, headers, body)
   if not token and status == 200 then
      token = headers["X-Token"]
      path  = "/resource"
      wrk.headers["X-Token"] = token
   end
end

发送 json


request = function()
    local headers = { }
    headers['Content-Type'] = "application/json"
    body = {
        mobile={"1533899828"},
        params={code=math.random(1000,9999)}
    }
    --这里用到了lua-cjson这个lua模块
    local cjson = require("cjson")
    body_str = cjson.encode(body)
    return wrk.format('POST', nil, headers, body_str)
end

mark:

在 wrk 的测试结果中,有一项为Requests/sec,我们一般称之为QPS(每秒请求数),这是一项压力测试的性能指标,通过这个参数我们可以看出应用程序的吞吐量。

 

发表评论

您的电子邮箱地址不会被公开。