最近的工作一直在與服務端效能優化打交道,QPS(每秒查詢率)的苛刻要求讓我這個以前也就用 node.js 寫寫部落格的人深刻地感覺到以前做的東西就是個玩具。所以最近也在嘗試瞭解一些壓測方面的知識。對於壓測工具,業界常用的有 jmeter、loadrunner、tcpcopy、apache bench、wrk(2) 等。作為壓測小白,結合專案實際情況(無需硬體監控、測試請求較簡單),在這裡選擇了上手使用 wrk2。本文記錄了使用過程中的一些心得體會。
wrk 簡介
wrk2 基於 wrk 進化而來,我們可以先了解一下 wrk 的使用。wrk 型別上與 apache bench(以下簡稱 ab)類似,都是終端上的工具,其使用多執行緒設計來進行請求的生成。相比 ab,wrk 最值得稱道的應該是它的自定義指令碼功能:wrk 支援使用 lua 指令碼來進行 HTTP 請求生成、響應處理以及自定義壓測報告等。 在基本的配置項上 wrk 也非常簡單:
$ wrk
wrk 4.1.0 [kqueue] Copyright (C) 2012 Will Glozer
Usage: wrk <options> <url>
Options:
# HTTP 連線數
-c, --connections <N> Connections to keep open
# 測試持續時間,如 2s 2m 2h
-d, --duration <T> Duration of test
# 開啟的執行緒數
-t, --threads <N> Number of threads to use
# 進階功能,使用 lua 指令碼
-s, --script <S> Load Lua script file
# 新增請求頭,如 "User-Agent: wrk"
-H, --header <H> Add header to request
# 列印詳細延遲統計
--latency Print latency statistics
# 設定請求超時時間,大於該時間的請求將被記錄
--timeout <T> Socket/request timeout
複製程式碼
對 url http://127.0.0.1:8080/index.html
進行開啟 12 個執行緒,開啟 400 個 HTTP 連線,持續 30s 的壓測,可表示如下:
wrk -t12 -c400 -d30s http://127.0.0.1:8080/index.html
複製程式碼
壓測結束後產出的報告內容也還比較詳細,都是一些壓測方比較關心的資料,比如延遲分佈、QPS 等,這裡就不過多贅述。
自定義指令碼功能
如果 wrk 常規的功能無法滿足需求,那麼這時就需要使用者自行編寫指令碼去進行處理。wrk 官方提供了一些示例指令碼以供參考。當然首先我們要掌握基本的 lua 語法,然後需要參考 wrk 暴露出的 lua 介面。wrk 在 setup、running、done 三個宣告週期內暴露了許多方法,分別用於執行緒的配置、請求和響應的處理以及自定義展示最終生成的測試報告。結合指令碼,wrk 能夠完成相當程度的複雜壓測需求。很多 wrk 的教程對此處並沒有詳細說明,但個人認為這裡才是 wrk 的精華所在。如果想熟練上手使用,應當對自定義指令碼的使用有所瞭解。
例如,如果想對每個請求增加一定延時,可在 wrk 暴露出的 delay
函式中進行設定:
function delay()
return math.random(10, 50)
end
複製程式碼
或者你想對 post 請求作壓測,則可以對 table wrk
進行設定:
wrk.method = "POST"
wrk.body = "foo=bar&baz=quux"
wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"
複製程式碼
wrk2
wrk2 是 wrk 的進化版,其號稱能夠提供穩定的吞吐量以及更精確的延時統計,反映到配置引數上就是 wrk2 增加了 --rate
引數用於設定吞吐量和--u_latency
引數用於顯示不正確(統計學角度)的延時統計。其他使用上 wrk2 與 wrk 區別不大,算是更加完善的工具。當然 wrk2 的作者十分謙虛,字裡行間流露出對 wrk 滿滿的崇敬之情,哈哈。
完。
本文首發於我的部落格(點此檢視),歡迎關注。