使用wrk進行性能測試

1 wrk介紹

wrk是一款現代化的HTTP性能測試工具,即便運行在單核CPU上也能產生顯著的壓力。它融合了一種多線程設計,並使用了一些可擴展事件通知機制,例如epoll and kqueue。一個可選的LuaJIT腳本能產生HTTP請求,響應處理和自定義報告,更詳細的腳本內容能夠參考scripts目錄下的一些例子。html

2 wrk下載和安裝

先安裝gitgit

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

下載wrk文件github

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

編譯成功後,目錄下就會有一個wrk文件。若是編譯過程當中,出現以下錯誤:web

若報錯gcc: Command not found,則需安裝gcc,參考wrk編譯報錯gcc: Command not foundjson

若報錯fatal error: openssl/ssl.h: No such file or directory,則須要安裝openssl的庫。多線程

sudo apt-get install libssl-dev 

或者app

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)。dom

詳細的命令行參數以下:工具

-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.

下面是輸出結果:post

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

若是要打印返回數據,可添加以下腳本:

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
相關文章
相關標籤/搜索