一款高性能的压测工具介绍--wrk

1、 wrk介绍

wrk是一款现代化的HTTP性能测试工具,即使运行在单核CPU上也能产生显著的压力。它融合了一种多线程设计,并使用了一些可扩展事件通知机制,例如epoll and kqueue。一个可选的LuaJIT脚本能产生HTTP请求,响应处理和自定义报告,更详细的脚本内容可以参考scripts目录下的一些例子。

2、 wrk下载和安装

先安装git

cd /usr/local/src
sudo yum install git -y

下载wrk

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

编译成功后,目录下就会有一个wrk文件。如果编译过程中,出现如下错误:

若报错gcc: Command not found,则需安装gcc

yum -y install gcc+ gcc-c++

若需升级gcc,则采用如下命令:

yum -y update gcc

若报错fatal error: openssl/ssl.h: No such file or directory,则需要安装openssl的库。

sudo apt-get install libssl-dev 

或者

sudo yum install  openssl-devel 

3、 一个简单的例子

wrk -t12 -c400 -d30s http://127.0.0.1:8080/index.html

它将会产生如下测试,12个线程(threads),保持400个HTTP连接(connections)开启,测试时间30秒(seconds)。

详细的命令行参数如下:

-c,    --connections(连接数):      total number of HTTP connections to keep open with each thread handling N = connections/threads

-d,    --duration(测试持续时间):     duration of the test, e.g. 2s, 2m, 2h

-t,    --threads(线程):            total number of threads to use

-s,    --script(脚本):             LuaJIT script, see SCRIPTING

-H,    --header(头信息):           HTTP header to add to request, e.g. "User-Agent: wrk"

       --latency(响应信息):         print detailed latency statistics

       --timeout(超时时间):         record a timeout if a response is not received within this amount of time.

下面是输出结果:

Running 30s test @ http://127.0.0.1:8080/index.html
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   635.91us    0.89ms  12.92ms   93.69%
    Req/Sec    56.20k     8.07k   62.00k    86.54%
  22464657 requests in 30.00s, 17.76GB read
Requests/sec: 748868.53
Transfer/sec:    606.33MB

结果解读如下:

  • Latency: 响应信息, 包括平均值, 标准偏差, 最大值, 正负一个标准差占比。
  • Req/Sec: 每个线程每秒钟的完成的请求数,同样有平均值,标准偏差,最大值,正负一个标准差占比。
  • 30秒钟总共完成请求数为22464657,读取数据量为17.76GB。
  • 线程总共平均每秒钟处理748868.53个请求(QPS),每秒钟读取606.33MB数据量。

4、 发送post请求例子

首先需要创建一个post.lua文件,内容如下:

wrk.method = "POST"
wrk.headers["uid"] = "127.0.0.1"
wrk.headers["Content-Type"] = "application/json"
wrk.body     ='{"uid":"127.0.0.1","Version":"1.0","devicetype":"web","port":"8080"}'

测试执行命令如下:

./wrk --latency -t100 -c1500  -d120s --timeout=15s -s post.lua http://127.0.0.1:8080/index.html

这个脚本加入了--lantency:输出结果里可以看到响应时间分布情况,

Running 2m test @ http://127.0.0.1:8080/index.html
  100 threads and 1500 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   127.26ms  157.88ms   2.44s    87.94%
    Req/Sec   177.91     45.09     1.10k    69.97%
  Latency Distribution
     50%   66.05ms
     75%  143.57ms
     90%  325.41ms
     99%  760.20ms
  2138290 requests in 2.00m, 3.17GB read
Requests/sec:  17804.57
Transfer/sec:  27.05MB

5、 带随机参数的get请求例子

如果想构造不同的get请求,请求带随机参数,则lua脚本如下:

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

6、 添加参数txt文件的get请求例子

如果要测试的url需要参数化,uids.txt文件内容如下:

100
101
102

lua脚本如下:

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

request = function()
   local path ="/GetInfo.aspx?u=%s&m=1"
   parms = urimap[counter%(table.getn(urimap) + 1)]
   path = string.format(path,parms)
   counter = counter + 1
   return wrk.format(nil, path) 
end

7、 添加参数txt文件的post请求例子

lua脚本如下:

urimap = {}
counter = 0
function init(args)
    for line in io.lines("uids.txt") do
       urimap[counter] = line
       counter = counter + 1
   end
   counter = 0
end

request = function()
   local body1 = '{"uid":"100%s'
   local body2 = '","name":"1"}'
   parms = urimap[counter%(table.getn(urimap) + 1)]
   path = "/getinfo"
   method = "POST"
   wrk.headers["Content-Type"] = "application/json"
   body = string.format(body1,parms)..body2
   counter = counter + 1
   return wrk.format(method, path, wrk.headers, body)
end

若参数txt中有转义字符,可用如下方法处理:

parms = string.gsub(urimap[counter%(table.getn(urimap) + 1)],'\r','')

如果要打印返回数据,可添加如下脚本:

a=1
function response(status, headers, body)
   if(a==1)
   then
           a=2
          print(body)
      end
end

8、 提交不同表单内容例子

lua脚本如下:

wrk.method = "POST"
wrk.body = ""
wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"

-- 提交不同表单内容
local queries = {
    "version=1.0",
    "version=2.0",
    "version=3.0"
}
local i = 0
request = function()
    local body = wrk.format(nil, nil, nil, queries[i % #queries + 1])
    i = i + 1
    return body
end

9、 访问多个url例子

如果要随机测试多个url,可参考wrk-scripts这个项目。
需要创建一个文件名为paths.txt,里面每行是一个要测试的url网址。lua脚本如下:

counter = 0

-- Initialize the pseudo random number generator - http://lua-users.org/wiki/MathLibraryTutorial
math.randomseed(os.time())
math.random(); math.random(); math.random()

function file_exists(file)
  local f = io.open(file, "rb")
  if f then f:close() end
  return f ~= nil
end

function shuffle(paths)
  local j, k
  local n = #paths
  for i = 1, n do
    j, k = math.random(n), math.random(n)
    paths[j], paths[k] = paths[k], paths[j]
  end
  return paths
end

function non_empty_lines_from(file)
  if not file_exists(file) then return {} end
  lines = {}
  for line in io.lines(file) do
    if not (line == '') then
      lines[#lines + 1] = line
    end
  end
  return shuffle(lines)
end

paths = non_empty_lines_from("paths.txt")

if #paths <= 0 then
  print("multiplepaths: No paths found. You have to create a file paths.txt with one path per line")
  os.exit()
end

print("multiplepaths: Found " .. #paths .. " paths")

request = function()
    path = paths[counter]
    counter = counter + 1
    if counter > #paths then
      counter = 0
    end
    return wrk.format(nil, path)
end
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容