請前往官方網站查看詳細的安裝指南
https://grafana.com/docs/k6/latest/set-up/install-k6/
此處簡單說明安裝方式。
針對常見 API:/users (POST 建立用戶)、/users/login、/myid。
設計場景:
模擬登入(POST /users/login)後呼叫受保護資源 /myid
下面是一個範例 k6 檔案:test.js
import http from 'k6/http';
import { check, sleep } from 'k6';
import { Trend } from 'k6/metrics';
export let latency = new Trend('latency_ms');
export let options = {
stages: [
{ duration: '10s', target: 5 }, // 漸增到 5 VUs
{ duration: '30s', target: 5 }, // 維持 5 VUs
{ duration: '10s', target: 0 }, // 使用者數量漸減
],
thresholds: {
// 95% 的請求應小於 3s
'http_req_duration': ['p(95)<3000'],
},
};
const BASE = __ENV.BASE_URL || 'http://localhost:3000';
function randomUserPayload() {
const id = Math.floor(Math.random() * 1000000);
return JSON.stringify({
username: `user_${id}`,
email: `user_${id}@example.com`,
password: 'Password123!'
});
}
export default function () {
// 模擬混合行為:先建立使用者,然後登入、然後存取 /myid
let createRes = http.post(`${BASE}/users`, randomUserPayload(), {
headers: { 'Content-Type': 'application/json' },
});
check(createRes, {
'create user status 201 or 200': (r) => r.status === 201 || r.status === 200,
});
let body;
try {
body = createRes.json();
} catch (e) {
body = {};
}
let loginPayload = JSON.stringify({
username: body.username || 'user_1',
password: 'Password123!'
});
let loginRes = http.post(`${BASE}/users/login`, loginPayload, {
headers: { 'Content-Type': 'application/json' },
});
const token = (loginRes.status === 200 && loginRes.json().token) ? loginRes.json().token : null;
if (token) {
let myidRes = http.get(`${BASE}/myid`, { headers: { Authorization: `Bearer ${token}` }});
check(myidRes, {
'myid 200': (r) => r.status === 200,
});
}
latency.add(createRes.timings.duration);
sleep(Math.random() * 2); // 模擬使用者思考的時間
}
說明:
使用預設的 stages:
k6 run test.js
也可以自訂設定,如同時 50 個 VU 持續跑 1 分鐘:
k6 run --vus 50 --duration 1m test.js
k6 執行完會輸出:
測試結果如下
C:\Users\gen\rust\sqlx_connect_demo>k6 run test.js
/\ Grafana /‾‾/
/\ / \ |\ __ / /
/ \/ \ | |/ / / ‾‾\
/ \ | ( | (‾) |
/ __________ \ |_|\_\ \_____/
execution: local
script: test.js
output: -
scenarios: (100.00%) 1 scenario, 5 max VUs, 1m20s max duration (incl. graceful stop):
* default: Up to 5 looping VUs for 50s over 3 stages (gracefulRampDown: 30s, gracefulStop: 30s)
█ THRESHOLDS
http_req_duration
✓ 'p(95)<3000' p(95)=2.89s
█ TOTAL RESULTS
checks_total.......: 55 1.049661/s
checks_succeeded...: 100.00% 55 out of 55
checks_failed......: 0.00% 0 out of 55
✓ create user status 201 or 200
CUSTOM
latency_ms.....................: avg=2760.95882 min=2588.8425 med=2735.2139 max=2965.1841 p(90)=2891.3154 p(95)=2942.31383
HTTP
http_req_duration..............: avg=1.38s min=784.5µs med=1.29s max=2.96s p(90)=2.84s p(95)=2.89s
{ expected_response:true }...: avg=2.76s min=2.58s med=2.73s max=2.96s p(90)=2.89s p(95)=2.94s
http_req_failed................: 50.00% 55 out of 110
http_reqs......................: 110 2.099323/s
EXECUTION
iteration_duration.............: avg=3.85s min=2.71s med=3.82s max=4.77s p(90)=4.52s p(95)=4.69s
iterations.....................: 55 1.049661/s
vus............................: 1 min=1 max=5
vus_max........................: 5 min=5 max=5
NETWORK
data_received..................: 43 kB 820 B/s
data_sent......................: 22 kB 419 B/s
running (0m52.4s), 0/5 VUs, 55 complete and 0 interrupted iterations
default ✓ [======================================] 0/5 VUs 50s