初めに
K6とは
goで作られた負荷テストツール。
ただし、ユーザ側のテストシナリオはjavascriptを使用する。
K6の利点
- goを利用しているので、少ないリソースでより多くの負荷をかけられる
- dockerイメージが用意されており、テスト実行だけならjavascript1つ用意するだけで可能
- gitlabなどのCIとの統合も容易
環境構築
- 実行環境の準備
- influxdbの構築(データストア)
- grafanaの構築(influxデータの読み取り)
- テストコード作成
実行環境(gitlab)および、grafana環境の作成は省略。
(今回は、gitlabのgrafanaを流用)
influxDBの構築
※influxv2には未対応なので、バージョンは1.8にすること。
docker-compose.yml
version: '3.8'
services:
influxdb:
image: influxdb:1.8
ports:
- "8086:8086"
environment:
- INFLUXDB_DB=k6
grafanaダッシュボードの作成
ダッシュボード2587(k6 Load Testing Results Dashboard)を下記の通りimportする。
https://grafana.com/grafana/dashboards/2587
サンプルテストコード
テストスクリプト
performance-test.js
import http from 'k6/http';
import { check } from 'k6';
import {htmlReport} from "https://raw.githubusercontent.com/benc-uk/k6-reporter/main/dist/bundle.js";
import {jUnit, textSummary} from "https://jslib.k6.io/k6-summary/0.0.1/index.js";
const puturl = 'http://ci-service-counter:9080/counter/increment';
const geturl = 'http://ci-service-counter:9080/counter';
export const options = {
stages: [
{ target: 10, duration: '5m' },
],
};
export default function () {
const headers = { 'Content-Type': 'application/json' };
const putJsonPayLoad = {"value": 1};
http.put(puturl, JSON.stringify(putJsonPayLoad), { headers: headers });
let countResponse = http.get(geturl);
check(countResponse, { "status is 200": (r) => r.status === 200 });
}
// レポート出力設定
export function handleSummary(data) {
console.log('Preparing the end-of-test summary...');
return {
stdout: textSummary(data, { indent: " ", enableColors: true }),
"summary.html": htmlReport(data),
'summary.xml': jUnit(data), // but also transform it and save it as a JUnit XML...
'summary.json': JSON.stringify(data), // and a JSON with all the details...
}
}
CI定義
gitlab-ci.yaml
nativeit-k6:
stage: it
when: manual
tags:
- docker
image:
name: loadimpact/k6:latest
entrypoint: ['']
services:
- name: ${CI_REGISTRY}/${CI_PROJECT_PATH}:1.2
alias: ci-service-counter
script:
- echo "executing local k6 in k6 container..."
- k6 run performance-test.js --out influxdb=http://192.**.**.**:8086/k6
artifacts:
paths:
- summary.html
- summary.xml
- summary.json
reports:
junit: summary.xml
テスト出力
grafana出力
k6テストレポート
ログ出力
log
✓ status is 200
checks.........................: 100.00% ✓ 107788 ✗ 0
data_received..................: 33 MB 110 kB/s
data_sent......................: 32 MB 107 kB/s
http_req_blocked...............: avg=8.82µs min=800ns med=1.5µs max=1.47s p(90)=2.5µs p(95)=3.1µs
http_req_connecting............: avg=182ns min=0s med=0s max=4.91ms p(90)=0s p(95)=0s
http_req_duration..............: avg=6.87ms min=3.47ms med=6.15ms max=306.01ms p(90)=9.59ms p(95)=11.52ms
{ expected_response:true }...: avg=6.87ms min=3.47ms med=6.15ms max=306.01ms p(90)=9.59ms p(95)=11.52ms
http_req_failed................: 0.00% ✓ 0 ✗ 215576
http_req_receiving.............: avg=46.72µs min=9.1µs med=47.1µs max=6.29ms p(90)=69.9µs p(95)=82.9µs
http_req_sending...............: avg=11.07µs min=4.2µs med=8.3µs max=7.43ms p(90)=21.1µs p(95)=28.6µs
http_req_tls_handshaking.......: avg=0s min=0s med=0s max=0s p(90)=0s p(95)=0s
http_req_waiting...............: avg=6.81ms min=3.42ms med=6.09ms max=305.94ms p(90)=9.52ms p(95)=11.45ms
http_reqs......................: 215576 718.541797/s
iteration_duration.............: avg=13.9ms min=7.63ms med=12.69ms max=1.48s p(90)=18.54ms p(95)=21.72ms
iterations.....................: 107788 359.270898/s
vus............................: 9 min=1 max=9
vus_max........................: 10 min=10 max=10