wrk 是一種高效的 HTTP 基準測試工具,能夠在單個多核 CPU 上運作時産生大量負載。它将多線程設計與 epoll 和 kqueue 等可伸縮事件通知系統相結合。是以,使用 wrk 使用較少的線程即可以壓測出非常可觀的請求資料。
并且我們可以通過一個可選的 LuaJIT(Lua) 腳本來提供更多的請求參數的定制,參數加密、鑒權請求等。
基礎使用
使用類 Unix 環境,在 CentOs 或 MacOs 上進行測試
wrk 開源 GitHub 位址: https://github.com/wg/wrk
通過 git clone 的形式下載下傳 源碼包,進入目錄下,執行 make ,然後開始編譯安裝,等待一會即可完成。
wrk 使用參數說明
-c, --connections: 總的連接配接數(每個線程處理的連接配接數=總連接配接數/線程數)
-d, --duration: 測試的持續時間,如2s(2second),2m(2minute),2h(hour)
-t, --threads: 需要執行的線程總數
-s, --script: 執行Lua腳本,這裡寫lua腳本的路徑和名稱,後面會給出案例
-H, --header: 需要添加的頭資訊,注意header的文法,舉例,-H “token: abcdef”,說明一下,token,冒号,空格,abcdefg(不要忘記空格,否則會報錯的)。
--latency: 顯示延遲統計資訊
--timeout: 逾時的時間
例子
wrk -t12 -c400 -d30s http://127.0.0.1:8080/index.html
該請求意思為: 使用 wrk 使用12個線程,400個連接配接,請求 url 30s
壓測結束後的結果:
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:每個線程每秒鐘的執行的連接配接數
Avg:平均
Max:最大
Stdev:标準差+/- Stdev: 正負一個标準差占比
Requests/sec:每秒請求數(也就是QPS),這是一項壓力測試的性能名額,通過這個參數可以看出吞吐量
Latency Distribution,如果命名中添加了
latency就會出現相關資訊
實戰
使用 wrk 對鑒權的接口進行調用壓測。由于是鑒權的接口,需要根據密鑰和時間戳動态的生成 secret 然後對後端進行請求,才能通過驗證。這裡我們引入 lua 腳本
由于 wrk 工具裡面 自帶 luaJit ,是以我們不用下載下傳。但是需要 md5 的子產品,是以需要使用 luarocks 來管理和下載下傳 lua 子產品和包。
安裝Luarocks 包管理工具
LuaRocks 是 Lua 子產品的包管理器。它允許您将 Lua 子產品建立并安裝為自包含包(稱為 rocks )。您可以在 Unix 和 Windows 上下載下傳和安裝 LuaRocks。官網:https://luarocks.org/
通過 curl 下載下傳
curl -o luarockt-3.0.3.tar.gz http://luarocks.github.io/luarocks/releases/luarocks-3.0.3.tar.gz
解壓 luarockt-3.0.3.tar.gz後,進入目錄下 指定到 wrk 裡 LuaJit 的目錄進行 configure
//這裡指定你自己的 `wrk` 路徑
./configure --with-lua=../wrk/obj
編譯安裝
make install
通過 Luarocks 安裝 md5 子產品
luarocks install md5
開始請求
我們需要像 url http://127.0.0.1:9000 網關進行 POST 請求,該網關會對請求進行鑒權和驗證,并判斷請求的實效性。是以我們需要在請求時動态改變請求參數,是以需要結合 Lua 腳本。
Lua 腳本 helloDemo.lua
md5=require("md5")
-- md5加密,拼接請求對象
function buildJson(json)
local apiKey = "abcdefg1234567"
local password = "qwerxxxx"
local timestamp = os.time() .. "000"
local secret = md5.sumhexa(apiKey .. timestamp .. password)
local body = json .. "×tamp=" .. timestamp .. "&secret=" .. secret
return body
end
wrk.method = "POST"
wrk.body = buildJson("serviceName=com.github.dapeng.service.HelloService&version=1.0.0&methodName=sayHello¶meter={\"body\": {\"request\": {\"bizTag\": \"order\", \"step\": 100}}}")
wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"
請求腳本
#!/usr/bin/env bash
time1=`date +%s`
echo "開始時間 `date +%Y%m%d%H%S`"
# wrk 安裝目錄 -s 後指定上面寫好的lua腳本
~/ideaspace/dapeng/benchmark/wrk/wrk -t4 -c400 --timeout 5s -d 60s -s lua/$1.lua --latency 'http://127.0.0.1:9000/api/e1bfd762321e409cee4ac0b6e841963c'
time2=`date +%s`
useTime=$[time2 - time1]
echo "結束時間 `date +%Y%m%d%H%S`"
echo "總共花費 $useTime s"
執行腳本
sh start-wrk.sh helloDemo
通過上面方式,我們就可以開始請求已鑒權的接口
總結
wrk 是一款高性能的 http 請求壓測工具,它使用了 Epoll 模型,使所有請求都是異步非阻塞模式的,是以對系統資源能夠應用到極緻,可以壓滿 cpu。
wrk 可以落站使用 Lua 腳本。該特性可以使我們通過 腳本動态的改變請求參數,對請求壓測提供的多樣性的選擇和定制。
後續
1. 去除 CO
關于 wrk 測試延遲分布不準确的問題,涉及到 Coordinated Omission 的原因,可 Google
在 src/wrk.c
将下面部分代碼注釋:
// if(complete / cfg.connections > 0) {
// int64_t interval = runtime_us / ( complete / cfg.connections);
// stats_correct(statistics,latency,interval);
關于 wrk 測試延遲分布不準确的問題,涉及到 Coordinated Omission 的原因,可 Google,也可以參考 wrk2
轉自 https://www.jianshu.com/p/26593d8c67be