簡單壓測http-wrk

關(guān)于壓測

常見的系統(tǒng)開發(fā)過程,壓測總是被置于整個周期的末尾,比如項目基本功能開發(fā)完成或者臨近上線時才開始準備壓測。這個時候往往累積了大量的“小問題”,導(dǎo)致壓測進行的比較緩慢,如果遇到前期“一壓就崩”的狀態(tài)則更讓人奔潰。按照我的個人經(jīng)驗,壓測之所以被經(jīng)常性的忽略,不外乎壓測腳本編寫麻煩,場景梳理費時費力,而且特別占用開始時間等因素。其實如果不考慮復(fù)雜的業(yè)務(wù)場景,可以使用wrk/ad等簡單http壓測工具對剛完成開發(fā)的接口進行針對性壓測,可以幫助后端開發(fā)人員更早的發(fā)現(xiàn)性能上的問題。

wrk

wrk 是一個簡單小巧的 http 性能測試工具,只有一個命令行,就能做很多基本的 http 性能測試。

wrk 本身是開源項目,代碼在 github 上:https://github.com/wg/wrk

安裝

wrk 具體的安裝過程可以參考其 github上的wiki:https://github.com/wg/wrk/wiki

本質(zhì)上wrk只能運行在類Unix 的系統(tǒng)上,所以Win10其實要開啟WSL(Windows SubLinux)才能正常安裝使用。當然,官方wiki里都有提及,按照wiki中的提示操作即可。

一鍵壓測

如果針對一個GET請求的Http接口,wrk基本上可以一鍵完成,比如:

# 使用wrk創(chuàng)建12個線程
# 維持 200 http并發(fā)連接
# 對指定接口【GET www.baidu.com】進行持續(xù)30秒的壓測
wrk -t12 -c200 -d30s https://www.baidu.com
壓測baidu

wrk命令的詳細選項如下:

  • -c, --connections: http并發(fā)數(shù)(默認使用http1.1,會復(fù)用TCP鏈接)
  • -d, --duration: 持續(xù)壓測時間, 比如: 2s, 2m, 2h
  • -t, --threads: 總線程數(shù)(建議為核心數(shù)的2倍即可)
    --s, --script: 指定執(zhí)行Lua腳本(可以使用Lua腳本實現(xiàn)更高階的功能)
  • -H, --header: 添加http header, 比如. -H 'Authorization: Bearer {token_value}' 來添加接口認證信息
  • --latency: 在控制臺打印出延遲統(tǒng)計情況
  • --timeout: http超時時間

用過lua腳本處理更復(fù)雜的情況

用命令行其實已經(jīng)可以覆蓋很多簡單的場景了。但是如果http接口稍微復(fù)雜些,就需要使用Lua腳本輔助。比如 接口為POST類型,body中有參數(shù),響應(yīng)需要寫斷言等等。

比如下面這個簡單的lua腳本,修改了全局對象wrk的三個屬性,method,body,headers,最終所有發(fā)出的http請求都會被影響。

wrk.method = "POST"
wrk.body   = "foo=bar&baz=quux"
wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"

Lua腳本執(zhí)行的簡單理解

想要編寫更加復(fù)雜的Lua腳本,需要了解wrk提供的幾個hook函數(shù)。

wrk提供的hook函數(shù)

wrk 提供了幾個 hook 函數(shù),可以用 lua 來編寫一些復(fù)雜場景下的測試:

  • setup

這個函數(shù)在目標 IP 地址已經(jīng)解析完,并且所有 thread 已經(jīng)生成,但是還沒有開始時被調(diào)用,每個線程執(zhí)行一次這個函數(shù)??梢酝ㄟ^ thread:get(name), thread:set(name, value) 設(shè)置線程級別的變量。

  • init

每次請求發(fā)送之前被調(diào)用??梢越邮?wrk 命令行的額外參數(shù),通過 – 指定。

  • delay

這個函數(shù)返回一個數(shù)值,在這次請求執(zhí)行完以后延遲多長時間執(zhí)行下一個請求,可以對應(yīng) thinking time 的場景。

  • request

通過這個函數(shù)可以每次請求之前修改本次請求的屬性,返回一個字符串,這個函數(shù)要慎用, 會影響測試端性能。

  • response

每次請求返回以后被調(diào)用,可以根據(jù)響應(yīng)內(nèi)容做特殊處理,比如遇到特殊響應(yīng)停止執(zhí)行測試,或輸出到控制臺等等。

這里提供一個我自己使用的簡單lua腳本

-- 打印respose到控制臺
response = function(status, headers, body)
    -- 這里其實可以解析body,寫斷言,針對性打印比較好
    print("status:", status)
    print("body:", body)
end

-- 自定義分析壓測結(jié)果
done = function(summary, latency, requests)

    local durations=summary.duration / 1000000    -- 執(zhí)行時間,單位是秒
    local errors=summary.errors.status            -- http status不是200,300開頭的
    local requests=summary.requests               -- 總的請求數(shù)
    local valid=requests-errors                   -- 有效請求數(shù)=總請求數(shù)-error請求數(shù)
  
    io.write("Durations:       "..string.format("%.2f",durations).."s".."\n")
    io.write("Requests:        "..summary.requests.."\n")
    io.write("Avg RT:          "..string.format("%.2f",latency.mean / 1000).."ms".."\n")
    io.write("Max RT:          "..(latency.max / 1000).."ms".."\n")
    io.write("Min RT:          "..(latency.min / 1000).."ms".."\n")
    io.write("Error requests:  "..errors.."\n")
    io.write("Valid requests:  "..valid.."\n")
    io.write("QPS:             "..string.format("%.2f",valid / durations).."\n")
    io.write("--------------------------\n")
  
end

wrk源碼中提供了一些常見的Lua腳本demo,可以參考:https://github.com/wg/wrk/tree/master/scripts

建議

其實這個建議就是官方的readme,簡單翻一下:

如果僅僅更改HTTP方法,修改路徑,添加標頭或正文的Lua腳本不會對壓測的性能產(chǎn)生影響。但是針對每個請求的操作(特別是構(gòu)建新的HTTP請求)以及使用 response()函數(shù) 必然會減少可以生成的負載量。

A user script that only changes the HTTP method, path, adds headers or a body, will have no performance impact. Per-request actions, particularly building a new HTTP request, and use of response() will necessarily reduce the amount of load that can be generated.

小技巧

-H參數(shù)和curl-H參數(shù)含義一致,所以在實際使用中可以先使用curl確認編寫的命令是否正確,或者也可以使用postman來確認,然后使用postman生成curl的請求命令即可。

使用 postman 生成 curl 命令

參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容