# K6
# 使用紀錄
## 20241124 ws chat 負載測試
* 一開始是測試 500 人
* 途中發現瓶頸卡在我的網路速度只有 20M
* 造成大量的 delay timeout 錯誤
* 在 pgsql connection pool 上限 5 個 & 超過 3 秒超時的狀況下完成 8X% 的處理
* 
* 其他的都卡在取得連線超時上
* 目前先簡單測試個 100 人做個紀錄
* 
* 這次測試使用的 script
```javascript
import ws from 'k6/ws';
import { check, sleep } from 'k6';
function generateToken() {
return Math.random().toString(36).substring(2, 15);
}
export const options = {
// stages: [
// { duration: '1m', target: 100 }, // 1 分鐘內增加到 100 個連線
// { duration: '3m', target: 500 }, // 3 分鐘內穩定在 500 個連線
// { duration: '1m', target: 0 }, // 1 分鐘內降到 0 個連線
// ],
stages: [
{ duration: '10s', target: 10 },
{ duration: '10s', target: 50 },
{ duration: '10s', target: 100 },
{ duration: '10s', target: 0 },
],
};
export default function () {
const token = generateToken();
const url = `wss://axum.kawa.homes/ws?token=${token}`;
// const url = `ws://127.0.0.1:3000/ws?token=${token}`;
const response = ws.connect(url, {}, (socket) => {
socket.on('open', () => {
// console.log(`Connected: ${token}`);
// 發送多條消息,模擬使用者交談
for (let i = 0; i < 10; i++) {
let messageContent = generateToken();
let data = {
message_type: "Message",
content: `k6 testing ${token} says ${messageContent}`,
from: token,
to: "All"
};
socket.send(JSON.stringify(data));
sleep(1); // 每隔 1 秒發送一次
}
// 關閉連線
socket.close();
});
});
check(response, { 'WebSocket status is 101': (r) => r && r.status === 101 });
}
```
* 測試後發現負載測試 100 人就會吃光我的網路頻寬了
* 要再測試更多人可能要等提升網路 or 其他方法了
## resource
* [官網 doc](https://k6.io/docs/)
* [docker image](https://hub.docker.com/r/grafana/k6/)
* [K6 使用上常見的參數設定(options)有哪些?](https://ithelp.ithome.com.tw/articles/10305862)
## 簡介
* k6 是一款現代的開源負載測試工具,它可以幫助開發者進行性能測試、壓力測試和容量規劃等工作。k6 的核心特點包括:
* 簡單易用:k6 使用 JavaScript 腳本語言進行編程,使用者可以快速上手。
* 現代化:k6 支持 ES6/ES7 的語法特性,具有現代化的開發體驗。
* 高效可靠:k6 的測試引擎基於 Go 語言開發,具有高效、可靠的特點。
* 高度可擴展:k6 支持多個使用者和腳本的同步運行,可以輕鬆地進行大規模的測試。
* 雲端部署:k6 Cloud 提供了方便的雲端部署和管理,並且提供了實時的監控和報告功能。
* k6 的使用場景包括:
* 測試 Web 應用程式的性能和穩定性;
* 測試 API 和微服務的性能和可靠性;
* 測試數據庫和消息佇列等基礎設施的性能和容量;
* 進行 CI/CD 測試和自動化測試等。
* 總體來說,k6 是一款現代化、高效可靠且易於使用的負載測試工具,適合用於各種不同的場景和應用。
## docker 版本的執行測試指令
```shell
# 測試線上
docker run --rm -i grafana/k6 run - <script.js
# 模擬 5 使用者,測試 5 秒
docker run --rm -i grafana/k6 run --vus 5 --duration 5s - <script.js
```
### 持久化資料
* output.json 要先建立,不然會建立成資料夾然後報錯
```shell
docker run -i -u "$(id -u):$(id -g)" -v "$(pwd)/output.json:/output.json" grafana/k6 run - <script.js -o json=/output.json
```
## 摸索紀錄
* 選擇使用 docker 版本
```shell
docker pull grafana/k6
```
* 測試是以撰寫的 js 檔案為基礎來執行的
# shell 範例
* 以當前資料夾的 script.js 內容執行測試
```shell
#!/bin/bish
rm output.json
touch output.json
docker run --rm \
-i \
-v $PWD/script.js:/app/script.js \
-v $PWD/output.json:/output.json \
-u $(id -u):$(id -g) \
-w /app \
grafana/k6 run script.js -o json=/output.json
```
# script 範例
```javascript
import http from 'k6/http';
import { sleep } from 'k6';
export let options = {
stages: [
{ duration: '30s', target: 10 },
{ duration: '1m30s', target: 30 },
{ duration: '20s', target: 0 },
],
};
export default function () {
// http.get('https://kawa.homes/blog');
// 使用 docker 測試本機的網址
http.get('http://host.docker.internal:3000/api/ttest');
sleep(1);
}
```