[ Tools ] - k6 壓測工具簡介

本次要介紹的是號稱開發者體驗最好的壓測工具 – k6

它在 GitHub 上擁有相當驚人的星星數( > 10w ),受歡迎的程度可想而知。

k6 的一大特點就是簡單易用,只要撰寫 ES6 JS 的腳本就可以進行壓測,

無論你在團隊中是擔任什麼角色,都可以輕易地上手這套工具。

在本文中會簡介 k6 的使用特性,並撰寫一個簡單的壓測腳本


前言

k6 在 2016 年加入開源的行列,並在 2021 年加入 Grafana Lab

你或許沒聽說過 Grafana Lab,但一定聽過 Grafana。

在這個 Lab 中有許多知名的開源專案,

如:GrafanaPrometheus ,以及最近越來越多人討論的 OpenTelemetry

k6 是一套強調開發者體驗  ( DE, Developer Experience ) 的壓測工具,

你並不需要去熟悉特定的 XML 或 DSL 格式,只要使用 ES6 JS 就可以做壓測了。

雖然是用 JS 寫腳本,但它並不運行在 NodeJS 之上。

實際上執行的部分是 Go 語言撰寫的,只是將 JS 的 runtime 內嵌在裡面而已。

雖然以開發者體驗著名, 但 k6 不僅僅是為了開發者而生,

它的願景是能讓整個工程團隊(Dev & SDET、DevOps & SRE、ST & QA)使用。
 

 

除此之外, k6 也整合了許多平台及工具,

並且支援了一般常見的協定,如 HTTP、WebSocket、gRPC 等。

無論在輸出測試報表上,或是串接 CI 實現自動化壓力測試,

k6 都有很完整的生態圈可以提供整合。

 

功能如此完善的一套壓測工具,它的市占假想敵是誰呢?

沒錯,就是在壓測工具當中行之有年的 JMeter!

而 k6 官方也非常逗趣的在官網上放了下面這張圖片。

(這個部分有戳到我的笑點,哈!)

內容翻譯如下:

還卡在不知如何使用 JMeter 嗎?

在過去,使用 JMeter 為一個微服務寫測試腳本至少要花 2週以上的時間。

相比之下,使用 k6 只需要半天就夠了。

 

功能介紹

功能的部分 Range 很廣,這邊著重於一般撰寫測試程式時較常用的功能做介紹。

HTTP Requests

k6 使用基於 JS 構建而成的測試程式碼來執行,

官方提供了 HTTP 相關的函式庫,讓我們在壓測過程中能夠更輕易地與目標服務構接

除了支援 REST 的常見動詞以外,也可以使用 batch 方法同時獨立地發送多個請求。

Check

k6 也融入了測試程式具有的 Assertion 元素,

透過 check 函式可以協助我們檢查回應的狀態與內容是否符合期望

檢查失敗並不會中斷整個測試程式,k6 會等全部的測試執完畢後,再將檢查結果彙整後統一輸出。

Threshold

Threshold 可以為測試程式加上門檻值,例如:平均回應時間 < 300 ms請求失敗比率 < 1%等條件。

等等,這概念怎麼感覺跟前一個 Check 很像?

事實上,Threshold 跟 Check 都是在驗證某個(些)指標是否符合我們對系統的期待。

最大的不同之處在於,當門檻值已經超越我們設定的標準時,

Threshold 可以要求終止測試程式,而 Check 不行。

Options

透過 Options 可以修改與測試執行過程有關的參數

像是每秒最大的請求數(RPS)測試要執行幾次(Itegrations)執行多久(Duration)等等…

許多 Options 都會有一個預設值,例如 :

  • RPS預設為0(無限制最大請求數)。
  • vus預設為 1(1 個虛擬使用者)。

這些預設值對於精準掌握你的測試情境 Input 相當重要,建議在實際撰寫測試腳本前可以先 overview 一下。

Options 可以從許多切入點注入設定,根據優先的順序(大到小)如下:

  1. 命令列參數(command-line flags)
  2. 環境變數(environment variables )
  3. 測試程式(exported script options)
  4. 組態檔案(config file)
  5. 預設值(defaults)

多元的注入方式,有利於測試執行時能夠依照不同的情境彈性地做切換。

基本安裝

再來我們來聊聊基本安裝的部分,

官方支援的環境非常的全面,不管是 LinuxMacOS 或是 Windows 都有支援。

筆者使用的環境是 Windows WSL2 Ubuntu 18.04,

所以這邊選用官方建議的 Ubuntu 安裝方式進行安裝:

sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install k6

接著可以使用 k6 version確認版本,如果可以看到版號就代表安裝完成了。

開始使用

安裝完畢之後我們來試著在 local 環境執行看,

一開始可以參考官方提供的入門範例,先看一下整體的效果後再做客製化。

這邊我先建立一個示範用的資料夾 my-k6-sample

mkdir my-k6-sample
cd my-k6-sample

 

接著把官方第一個範例存成工程師最熟悉的 hello 版本—hello-k6.js

import http from 'k6/http';
import { sleep } from 'k6';

export default function () {
  http.get('https://test.k6.io');
  sleep(1);
}


好了之後我們就要來執行第一個測試程式啦!

k6 是以 CLI 操作為主的測試工具,這是便於自動化的一大關鍵。

只要輸入 k6 run {file_path}就可以了,這邊我們就直接動手來跑跑看!

k6 run hello-k6.js

嗯…不得不說,這輸出的編排看起來蠻舒服的!

這邊簡單帶一下每個區塊代表的意思:

  • 綠色部分沒什麼好多說的,就是我們輸入的執行指令
  • 紅色部分測試情境的參數 。以這個案例來說,代表我們宣告 1 個 VU(虛擬使用者)執行 1 次測試案例
  • 黃色部分很重要,這是測試結果的輸出指標,強烈建議事先讀過官方提供的 Metrics 篇,以便掌握各項指標所代表的意義。

 

在上面的測試中,我們宣告了 1 個 VU 執行 1 次測試案例。

它們在 Options 中分別代表 vusiterations

但如果仔細回顧,會發現我們根本沒有設定這兩個參數。

這其實就是所謂的預設值啦(vusiterations的預設值皆為1)。

 

接著我打算稍微修改一下測試情境:我希望讓 5 個 VU 一起執行 15 次測試

也就是說理論上平均 1 個 VU 會需要執行 15 / 5 = 3 次。

不過在 k6 的機制裡面,每個 VU 的執行次數並不是用平均來計算的。

它是盡可能地讓每個 VU 都以最快的速度去執行,然後去累計 total 是否達到我們期望的次數。

所以在某些時候,可能會有部分 VU 執行次數比其他的還多的狀況產生。

如果你希望讓每個 VU 執行的次數一樣的話,可參考官方提供的 Scenarios: Per VU iterations

 

扯遠了,我們拉回來繼續執行剛才的範例。

你可以自由選擇要在哪個 Options 注入點調整參數值,這邊示範的是使用命令列參數調整的方式。

$ k6 run hello-k6.js --vus 5 --iterations 15

這邊一樣簡單的來解讀一下數據:

  • scenarios 中的  15 iterations shared among 5 VUs代表由 5 個 VU 一起執行 15 次測試
  • 一共執行了 4.4 秒。
  • 下方的 iterationsvus都是我們預期的數值。

結語

結語的部分就用一張圖做為結束。

沒有啦,其實我想表達的是: k6 整合的資源真的比我想像中的還廣大很多

原本是想要把輸出結果的 part 也寫進去,

翻到後來發現實在是太多東西了,只好以後有時間再整理成文章。

 

來認真地做一下總結:

k6 是一套我認為很「先進」的壓測工具,

在地上能跑,在雲上也能飛(這邊指的是 k6 cloud,不過價格又是後話了…)。

官方本身的文件我覺得算是非常完整,

除了教你怎麼使用以外,連常用的壓測情境都直接幫你寫好扣了。

CI/CD 的部分也支援了許多大眾常用的工具。

希望日後可以有越來越多人開始討論這套工具!

 

內容如有勘誤,再請告知,謝謝。

參考