wrk压力测试使用心得(详细)

wrk是一种现代HTTP基准测试工具,能够在单个多核CPU上运行时产生大量负载。它结合了多线程设计和可扩展的事件通知系统,如epoll和kqueue,以及使用了redis的'ae'事件循环,可以用很少的线程压出很大的并发量。

一、wrk下载和安装

可以从github上下载wrk源码,如果没有git可以百度安装一下。

wrk是在服务器上执行的压测工具,所以需要在服务器上安装

1.window系统打开git窗口,在目录中使用此命令下载wrk(如果服务器中有git,则在服务器中使用此命令下载即可):

git clone https://github.com/wg/wrk.git wrk

2.把下载下来的wrk文件夹打个压缩包,打开连接linux服务器的工具(如Xshell),在服务器上创建一个存放wrk文件和测试用的文件的文件夹

3.进入创建的文件夹后使用rz 命令上传wrk压缩包,然后解压

4.解压后,进入wrk文件夹,使用make命令编译

cd wrk

make

5.编译成功后,会在项目路径下生成可执行文件wrk,随后就可以使用了。也可以拷贝到/usr/local/bin,这样就可以在任何路径直接使用wrk了。

ln -s /xxx/xxx/wrk /usr/local/bin

6.输入wrk,如果有以下显示,则说明安装成功了

wrk压力测试使用心得(详细)_第1张图片

 

二、压力测试

1、最简单的压力测试示例,get请求,固定url固定参数

wrk -t10 -c30 -d 2s -T5s --latency http://www.baidu.com

注意:我这里试的粘贴过去会有问题,建议手敲一下

参数释义:

-t:需要模拟的线程数

-c:需要模拟的连接数

-d:测试的持续时间

----timeout 或 -T:超时的时间 

--latency:显示延迟统计

-s 或 --script:      lua脚本,使用方法往下看

-H, --header:      添加http header, 比如. "User-Agent: wrk"

 

测试结果:

wrk压力测试使用心得(详细)_第2张图片

测试结果解析

Running 2s test @ http://www.baidu.com
  10 threads and 30 connections

                                                     平均值            标准差        最大值      正负一个标准差占比
线程状态  Thread Stats                   Avg              Stdev           Max         +/- Stdev
响应时间  Latency                        168.45ms       265.72ms     1.48s          87.68%
每线程每秒完成请求数Req/Sec     25.78          26.22          120.00        86.55%         
  Latency Distribution      延迟统计
     50%   31.15ms           有50%的请求执行时间是在31.15ms内完成
     75%  243.14ms          有75%的请求执行时间是在243.14ms内完成
     90%  479.94ms          有90%的请求执行时间是在479.94内完成
     99%    1.31s               有99%的请求执行时间是在1.31s内完成
  365 requests in 2.01s, 5.55MB read      2秒执行了365个请求,读了5.55MB数据

Socket errors: connect 29, read 2, write 0, timeout 0     错误    : 连接错误:29     读错误:2
Requests/sec:    182.02        每秒请求数(也就是QPS)
Transfer/sec:      2.77MB      每秒钟读取2.77兆数据量

 

复杂一些的一些则需要用到lua脚本

lua脚本学习可看此地址 http://www.runoob.com/lua/lua-tutorial.html

执行命令为  wrk -t5 -c10 -d 1s -T5s --latency -s test1.lua  http://www.baidu.com

-s test1.lua 则是执行lua脚本

2.wrk发post请求

执行命令为  wrk -t5 -c10 -d 1s -T5s --latency -s test1.lua  http://172.18.11.11/queryUserByName

lua脚本为:body中是参数  ,headers一般不用传,看个人需要

request = function()
   headers = {Connection= "keep-alive"}
   body = "name=中文"
   return wrk.format("POST",path,headers,body)
end

3.wrk发送随机参数-(get)

执行命令为  wrk -t5 -c10 -d 1s -T5s --latency -s test1.lua  http://www.baidu.com

request = function()
num = math.random(1000,9999)
   path = "/test.html?t=" .. num
   return wrk.format("GET", path)
end

path这个字符串会拼到 http://www.baidu.com 后

wrk.format这个方法简介:

根据参数和全局变量wrk生成一个http请求

函数签名: function wrk.format(method, path, headers, body)

     method:http方法,比如GET/POST等

     path: url上的路径(含参数) 如 /index, /index?name=xiaoming&id=123

     headers: http header(请求头)

     body: http body(参数)

4.wrk从文件中依次选择参数

   适用于用多条固定的参数测试

   先在执行脚本同级目录下创建一个文件,例如:ids.txt

   文件内容为:

   1

   2

   3

执行命令为  wrk -t5 -c10 -d 1s -T5s --latency -s test1.lua  http://www.baidu.com

lua脚本文件内容为:

idArr = {}
falg = 0
function init(args)
    for line in io.lines("ids.txt") do
       print(line)
       idArr[falg] = line
       falg = falg + 1
   end
   falg = 0
end

request = function()
   local path ="/getInfo?id=%s"
   parms = idArr[falg%(table.getn(idArr) + 1)]
   path = string.format(path,parms)
   falg = falg + 1
   return wrk.format(nil, path) 
end

会把取到的值拼到 http://www.baidu.com后

其中

for line in io.lines("ids.txt") do      //io.lines()是从ids.txt中取一行数据

       print(line)        

       idArr[falg] = line

       falg = falg + 1

end

table.getn()是获取集合的长度

wrk.format()方法上面有介绍

5.wrk传中文:

如果要传的参数中有中文,则需要转码,lua脚本如下:

需要加入encodeParm()方法,中文参数调用其转码

idArr = {}
falg = 0
function init(args)
    for line in io.lines("ids.txt") do
       print(line)
       idArr[falg] = line
       falg = falg + 1
   end
   falg = 0
end

function encodeParm(s)
  s = string.gsub(s,"([^%w%.%-])",function(c) return string.format("%%%02X",string.byte(c))end)
print(string.gsub(s," ","+"))
return string.gsub(s," ","+")
end

request = function()
   local path ="/user/identitySelect?name=%s"
   parms = idArr[falg%(table.getn(idArr) + 1)]
   parms = encodeURL(parms)
   path = string.format(path,parms)
   --path = encodeParm(path)
   falg =falg + 1
  print("path",path)
   return wrk.format(nil, path)
end

6.发送多个请求

执行命令为  wrk -t5 -c10 -d 1s -T5s --latency -s test5.lua  http://www.baidu.com

lua脚本为:

init = function(args)
   local r = {}
   r[1] = wrk.format(nil, "/info/getInfoById?id=100001&channel=0")
   r[2] = wrk.format(nil, "/info/getByName?name=aaa&startindex=0&length=10")
   r[3] = wrk.format(nil, "/info/getByUserId?id=88888888")

   req = table.concat(r)
end

request = function()
   return req
end

 

7.lua声明周期

共有三个阶段,启动阶段,运行阶段,结束阶段

启动阶段

function setup(thread) :

wrk会在线程初始化但还没有启动的时候调用setup(thread)方法。且每个线程都会调用一次,并传入测试线程的对象thread作为参数。

   thread.addr 设置请求需要打到的ip

   thread:get(name) 获取线程全局变量

   thread:set(name, value) 设置线程全局变量

   thread:stop() 终止线程

运行阶段:

function init(args) -- 每个线程都会先调用1次,其中可以做一些初始化工作,比如读测试数据

function delay() -- 每次请求调用1次,发送下一个请求之前的延迟, 单位为ms

function request() -- 每次请求调用1次,返回http请求

function response(status, headers, body) -- 每次请求调用1次,返回http响应

 

如有不当之处,还望指出!

 

你可能感兴趣的:(java,后端)