wrk是一款現代化的HTTP性能測試工具,即便運行在單核CPU上也能產生顯著的壓力。它融合了一種多線程設計,並使用了一些可擴展事件通知機制,例如epoll and kqueue。一個可選的LuaJIT腳本能產生HTTP請求,響應處理和自定義報告,更詳細的腳本內容能夠參考scripts目錄下的一些例子。html
先安裝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
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數據量。
首先須要建立一個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
若是想構造不一樣的get請求,請求帶隨機參數,則lua腳本以下:
request = function() num = math.random(1000,9999) path = "/test.html?t=" .. num return wrk.format("GET", path) end
若是要測試的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
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
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
若是要隨機測試多個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