K6 基本介紹、安裝及實作
k6 在 2016 年加入開源的行列,並在 2021 年加入 Grafana Lab 。是用 Go 語言編寫的一種高效能的負載測試工具。 k6 沒有 GUI,不過能使用 JavaScript 來撰寫腳本,並提供許多範例及testing API 。
整合工具
k6 也整合了許多平台及工具,並且支援了一般常見的協定,如 HTTP、WebSocket、gRPC 等。在輸出測試報表或是串接 CI 實現自動化測試,k6 都有很完整的生態圈可以提供整合。
程式效能
k6 的單個實例可以同時執行 30,000-40,000 個虛擬使用者( VUs )。 在某些情況下,此數量的VU最多可以生成300,000 HTTP 每秒請求 ( RPS )。
安裝 k6
k6 提供多種安裝方式,可以在 Linux, Mac, Windows 及 Docker 上安裝,以下介紹 Mac 及 Windows 兩種
MacOS:使用Homebrew
$ brew install k6
Windows:
$ choco install k6
或是官方下載安裝檔
安裝完成後可以使用 k6 version
確認版本
$ k6 version
執行 k6
首先,建立一個 k6-sample 並新增一個 script.js
$ mkdir k6-sample
$ cd k6-sample
建立一個簡單的情境:每一秒打一次http://test.k6.io
import http from 'k6/http';
import { sleep } from 'k6';
export default function () { //default函式是每次執行都會做的動作,會反覆執行,HTTP請求要放在其中
http.get('https://test.k6.io');
sleep(1);
}
在 CLI 執行 k6 run {file_path}
$ k6 run script.js
執行結果:
scenarios:測試情境的參數 。說明這次宣告 1 個 VU(虛擬使用者)執行 1 次測試案例。
其他的各項參數 (METRIC NAME) 是測試結果的輸出指標,可以參考下方表格或是官方的 metrics。
METRIC NAME | TYPE | DESCRIPTION |
vus | Gauge | 當前活躍虛擬使用者數 |
vus_max | Gauge | 最大可能的虛擬用戶數(VU 資源已預先分配,確保在擴展負載級別時不會影響性能) |
iterations | Counter | 該腳本執行一次所花費的時間 |
iteration_duration | Trend | 完成一次完整迭代所花費的時間,包括設置和拆卸所花費的時間 |
dropped_iterations | Counter | 由於缺少 VU或時間不足而未啟動的迭代次數。 |
data_received | Counter | 接收到的數據量 |
data_sent | Counter | 發送的數據量 |
checks | Rate | 檢查成功率 |
http_reqs | Counter | 計算測試總共發了多少 request |
http_req_blocked | Trend | 發起請求之前阻塞(等待空閒 TCP)所花費的時間 |
http_req_connecting | Trend | 建立與 server 的 TCP 連接所花費的時間 |
http_req_tls_handshaking | Trend | 與 server 握手 TLS 所花費的時間 |
http_req_sending | Trend | API 發送到 server 所花費的時間 |
http_req_waiting | Trend | API 從 server 等待回應所花費的時間 |
http_req_receiving | Trend | API 從 server 回來所花費的時間 |
http_req_duration | Trend | API 請求的總時間。它等於 http_req_sending + http_req_waiting + http_req_receiving(即遠程服務器處理請求和響應需要多長時間,沒有初始 DNS 查找/連接時間) |
http_req_failed | Rate | API 失敗的機率(預設 status code 是 200) |
自訂參數 options
自訂參數可以直接在 cmd 指令輸入或是在程式碼上加入 options ,填入後 k6 便會依照參數執行。
可用參數可以參考官方文件
例如:要求 k6 模擬 10 個使用者連續執行該API 15 次。
可以在 cmd 加上以下參數 vus 及 interations
$ k6 run script.js --vus 10 --iterations 15
或是在程式加上 options
export const options = {
vus: 10, //模擬使用者數量
iterations: 15 //模擬執行次數
};
如下圖
執行 script.js 後可以發現 k6 的確模擬了 10 個使用者並執行呼叫 API 15 次
k6 的生命週期
k6 的生命週期分為 init、setup、VU code、treadown,若是在執行測試前後有一些特殊需求,可以在 setup 函式與 teardown 函式上添加需要執行的事項
測試階段 | 目的 | 範例 | 執行次數 |
---|---|---|---|
1. init | 載入檔案、導入模塊、聲明生命週期函數 | 打開 JSON 文件,導入 模組 | 每個虛擬使用者 (VU) 都會執行 |
2. Setup | 建立處理數據,VU 間共享數據 | 呼叫 API 啟動測試環境 | 執行一次 |
3. VU code | 執行測試函數 | 發出 https 請求,驗證 response | 每次迭代都會執行 |
4. Teardown | 設置代碼的處理結果,停止測試環境 | 檢核設定是否有特定結果 | 執行一次 |
例如:在執行前先取得 API 資料,執行後印出 log,完成後再印出另一個 log
import http from 'k6/http';
export function setup() {
const res = http.get('https://example.com/message');
return { data: res.json() };
}
export function teardown(data) {
console.log("EDED94神奇");
}
export default function (data) {
console.log(JSON.stringify(data));
}
從下圖的執行成果,可以看到 INFO[0000] 將取得的 API 的資料透過 console.log 印出
透過上面的自訂參數與生命週期函式,我們可以自行組合需要的測試條件
例如:模擬使用者隨時間變化改變,並在測試完成後下一個 log
import http from 'k6/http';
import { check, sleep } from 'k6';
export let options = {
stages: [ // stages 可以模擬使用者持續增加或遞減
{ duration: '20s', target: 20 }, // 使用者在 20 秒內增加到 20 人
{ duration: '30s', target: 10 }, // 30秒內降至 10 人
{ duration: '10s', target: 0 }, // 最後 10 秒逐漸降 0 人
],
};
export function teardown() { // 在 default 執行完後顯示 console.log
console.log("EDED94神奇");
}
export default function () {
let res = http.get('https://example.com/message');
/**
* check 類似斷言功能,但不會真的中斷執行,只是會返回 check 的數據百分比
* 在這邊確認回傳狀態是 200,如果有非 200 的狀態會在結束後統一顯示結果
*/
check(res, { 'status was 200': (r) => r.status == 200 });
sleep(1);
}
心得
使用 k6 意外的簡單。安裝上不需要繁瑣的設定,官方文件清晰明了並附上了程式碼範例,讓人可以立刻使用。生態圈也有跟常用的 Swagger 整合,對新手來說非常的友善。
參考
k6
https://clouding.city/tool/k6/
https://www.tpisoftware.com/tpu/articleDetails/1597
https://blog.darkthread.net/blog/k6-load-testing/