vegeta 是一個 HTTP 壓力測試工具,使用 Go 編寫,用命令行互動,並且可以生成匯總和圖表作為結果分析。
HTTP load testing tool and library. It's over 9000!
基本使用#
詳細使用方式可以參考 README 裡的內容。可以分為兩種方式使用:命令行互動和作為庫引入 Go 程式。我這邊使用了 brew 安裝了 vegeta,整個測試過程是使用 Go 編寫了一個腳本來進行測試,具體可以參考程式碼片段
我並沒有使用庫的形式來引入,而是使用exec.Command()
函數來執行命令行。
具體使用到的 vegeta 命令
- attack: 呼叫 API 的命令,rate 代表每秒呼叫次數,duration 表示呼叫幾秒,body 指的是 post 請求的請求體,name 是指為這次測試命名「可不填」,tee 是生成 bin 原始檔「類似 raw 格式照片,可以用 bin 轉換成很多別的格式」,report 是生成報告,這裡是在命令行輸出。
echo "POST http://172.17.1.36:30898/hello" | vegeta attack -rate=2000 -duration=1s -body=query.json -timeout=0 -name=hello | tee ./result/results-null.bin | vegeta report
- 生成報告檔案,這裡是根據 bin 原始檔案生成 txt 檔案
vegeta report -type=text results-query.bin > repost.txt
- 生成分析圖表,使用 plot 可以生成可互動的圖表,需要將多個結果合併到一個圖表的時候需要注意,在使用第一個命令的時候務必加上 - name 參數為其命名。
vegeta plot results-null.bin results-sleep.bin results-query.bin > plot-all.html
測試場景#
使用 Java 和 Go 編寫兩個 REST 服務,分別測試 3 個 API,在 k8s 中單副本和 5 副本的情況。API 資訊如下:
- 直接返回
- sleep 2 秒再返回
- 查詢 Elasticsearch 的 10000 條資料,每條資料 500 字節
Elasticsearch 集群資訊
- 節點數量:2
- 版本:7.4.1
- CPU:8 個 Intel (R) Xeon (R) Silver 4114 CPU @ 2.20GHz,每個 1 core
- 內存:31G
Kubernetes 資訊
- 版本:1.16.15
- 節點數量:7「1 master, 6 worker」
指定 Deployment 調度到同一個節點,兩個 Deploymnet 都分配了 2G 的內存
測試步驟#
將 Go 腳本打包好後,在同目錄下創建配置文件config.ini
[address]
null = "POST http://172.17.1.36:30898/hello"
sleep = "POST http://172.17.1.36:30898/sleep"
query = "POST http://172.17.1.36:30898/es"
[param]
rate = 2000
其中 address 指的是要呼叫的 API 地址和方法,rate 指的是每秒呼叫的次數「我這裡是只呼叫了 1s」
執行腳本,等待……
測試結果#
每個 API 生成了 3 個檔案
- results-*.bin 檔案:測試原始檔案
- report-*.txt 檔案:報告檔案
- plot-*.html 檔案:單個結果圖表檔案
首先是 Java
- 空介面
Requests [total, rate, throughput] 2000, 2004.21, 1996.25
Duration [total, attack, wait] 1.002s, 997.9ms, 3.98ms
Latencies [min, mean, 50, 90, 95, 99, max] 2.114ms, 28.492ms, 11.283ms, 77.584ms, 90.305ms, 111.482ms, 150.836ms
Bytes In [total, mean] 10000, 5.00
Bytes Out [total, mean] 0, 0.00
Success [ratio] 100.00%
Status Codes [code:count] 200:2000
字段解釋
Requests(請求數):
- total 表示總請求數,這裡是 2000。
- rate 表示每秒發起的請求數,這裡是 2004.21。
- throughput 表示每秒成功完成的請求數,這裡是 1996.25。
Duration(持續時間):
- total 表示測試總時間,這裡是 1.002 秒。
- attack 表示攻擊時間,即實際發送請求的時間,這裡是 997.9 毫秒。
- wait 表示在攻擊期間所有請求的總等待時間,這裡是 3.98 毫秒。
Latencies(響應時間):
- min 表示最小響應時間
- mean 表示平均響應時間
- 50, 90, 95, 99 表示分位數「不是很懂這個指標表示的是什麼」,分別是 50%,90%,95%,99% 的響應時間
- max 表示最大響應時間
Bytes In(接收位元組數):
- total 表示所有請求的總接收位元組數
- mean 表示每個請求的平均接收位元組數
Bytes Out(發送位元組數):
- total 表示所有請求的總發送位元組數
- mean 表示每個請求的平均發送位元組數
Success(成功率):
- ratio 表示成功的請求佔總請求的百分比
Status Codes(狀態碼):
- code 表示每個狀態碼出現的次數。
當我把 3 個結果合併在一起的時候,響應時間基本上是一個線性增長,且查詢時間最後漲到了 3m 多
- Go
sleep 和空介面都相當穩定,查詢介面的響應時長也比 Java 好了很多
接下來是把兩個服務都添加到 5 個副本之後的結果
- Java
只能說 sleep 介面的穩定性得到了提升,不會線性增長,但是查詢介面的響應時間還是有點離譜
- Go
查詢介面的響應時長並沒有太大的提升
總結#
對於查詢介面而言,可能瓶頸會出現在 Elasticsearch 端,這裡先不測試了。
從圖表來看,Go 處理並發能力確實略胜一籌。
vegeta 這個工具還有很多玩法沒有去使用,相對於 Jmeter,雖然命令行不是很友好,但是生成的結果相當的直觀。