タダです.
API のリプレイスをしている中で負荷試験やシナリオ試験ができていなくて,そういったテストをできるようなツールとして k6 を同僚から教えてもらって試してみました.この記事で k6 を触ってみたので試したことなどまとめていきます.
自分に新しい刺激をいれてみたくてテストでk6を使い始めてるhttps://t.co/14XVYZ7Mg4
— Sadayoshi Tada🎉 (@tada_infra) 2021年8月5日
k6 とは
k6 は JavaScript でかけるオープンソースの負荷テストツールです.特徴として次のようなものがあります.
k6 の導入
k6 の導入は簡単で Mac なら以下のコマンド1発で終わります.
$ brew install k6
k6 でテストを実行する
k6 でのテストを実行していきます.まずは Getting Started な内容で書いていきます.export default function ()
の中で API を呼び出す順番だったり,条件を記述してシナリオを作っていきます.
import http from 'k6/http'; import { sleep } from 'k6'; export default function () { http.get('https://test.k6.io'); sleep(1); }
上記のテストを実行してみます.テストの実行は k6 run テストファイル名
で行います.
% k6 run test.ts /\ |‾‾| /‾‾/ /‾‾/ /\ / \ | |/ / / / / \/ \ | ( / ‾‾\ / \ | |\ \ | (‾) | / __________ \ |__| \__\ \_____/ .io execution: local script: test.ts output: - scenarios: (100.00%) 1 scenario, 1 max VUs, 10m30s max duration (incl. graceful stop): * default: 1 iterations for each of 1 VUs (maxDuration: 10m0s, gracefulStop: 30s) running (00m01.3s), 0/1 VUs, 1 complete and 0 interrupted iterations default ✓ [======================================] 1 VUs 00m01.3s/10m0s 1/1 iters, 1 per VU data_received..................: 132 kB 105 kB/s data_sent......................: 516 B 411 B/s http_req_blocked...............: avg=198.22ms min=198.22ms med=198.22ms max=198.22ms p(90)=198.22ms p(95)=198.22ms http_req_connecting............: avg=8.85ms min=8.85ms med=8.85ms max=8.85ms p(90)=8.85ms p(95)=8.85ms http_req_duration..............: avg=51.22ms min=51.22ms med=51.22ms max=51.22ms p(90)=51.22ms p(95)=51.22ms { expected_response:true }...: avg=51.22ms min=51.22ms med=51.22ms max=51.22ms p(90)=51.22ms p(95)=51.22ms http_req_failed................: 0.00% ✓ 0 ✗ 1 http_req_receiving.............: avg=26.08ms min=26.08ms med=26.08ms max=26.08ms p(90)=26.08ms p(95)=26.08ms http_req_sending...............: avg=78µs min=78µs med=78µs max=78µs p(90)=78µs p(95)=78µs http_req_tls_handshaking.......: avg=172.55ms min=172.55ms med=172.55ms max=172.55ms p(90)=172.55ms p(95)=172.55ms http_req_waiting...............: avg=25.06ms min=25.06ms med=25.06ms max=25.06ms p(90)=25.06ms p(95)=25.06ms http_reqs......................: 1 0.796752/s iteration_duration.............: avg=1.25s min=1.25s med=1.25s max=1.25s p(90)=1.25s p(95)=1.25s iterations.....................: 1 0.796752/s vus............................: 1 min=1 max=1 vus_max........................: 1 min=1 max=1
テスト実行後に表示されるアウトプットが多数表示されますが,それぞれの意義は次のとおりです.
表示名 | 説明 |
---|---|
execution | k6 の実行モードを表わし,local か cloud がある |
output | テストの結果がでるが,デフォルトは出力されない |
script | テストファイルのパス |
scenarios | テストシナリオの概要 |
data_received | 受信したデータの量 |
data_sent | 送信したデータの量 |
http_req_blocked | リクエストを開始するまでにブロックされていた時間 |
http_req_connecting | リモートホストとのTCP接続確立に要した時間 |
http_req_duration | サーバーがリクエストを受け付けてからレスポンスを返すまでにかかった時間 |
http_req_failed | リクエストの失敗割合 |
http_req_receiving | サーバーからのレスポンスデータの受信にかかった時間 |
http_req_sending | サーバーへのデータ送信にかかった時間 |
http_req_tls_handshaking | サーバーとのTLSセッションのハンドシェイクにかかった時間 |
http_req_waiting | サーバーからのレスポンスを待つ時間 |
http_reqs | k6 が生成したHTTPリクエストの総数 |
iteration_duration | テスト1回の反復処理に要した時間 |
iterations | テストスクリプトを実行した回数の総計 |
vus | アクティブな仮想ユーザー数 |
vus_max | 最大の仮想ユーザー数 |
関連情報
k6 のオプション
k6 ではテストを作っていく時に様々なオプションがあります.ここでは自分が使ってみてよく使いそうなものをまとめていきます.
ユーザーの増加
サービスを本番に載せたときに稼働状況からユーザーが段階的に増えることはよくあると思います.そんなケースを k6 で表現できます.以下のコードは最初はユーザー数5だけど,10秒ごとに30->50->80と target
で指定した分,ユーザー数が段階的に増えるようなイメージです.
export let options = { scenarios: { 'api_scenario': { executor: 'ramping-vus', startVUs: 5, stages: [ { duration: '10s', target: 30}, { duration: '10s', target: 50}, { duration: '10s', target: 80}, { duration: '10s', target: 110}, { duration: '10s', target: 140}, { duration: '10s', target: 170}, { duration: '10s', target: 200} ], gracefulRampDown: '10s' } }
テスト結果のイメージとしては次のよう表示になり,api_scenario
部分のパラメーターがどんどん増えるような動作をします.
running (1m20.0s), 000/200 VUs, 38 complete and 172 interrupted iterations api_scenario ✓ [======================================] 170/200 VUs
テストのサマリーを好みの表示にする
テスト結果をシステムの目標値,例えばレスポンスタイムの99パーセンタイルでみたら 0.5 秒以下になるかみたいなのをすぐに見れると楽ですよね? そういったテストの結果の表示をカスタマイズできます.
export let options = { summaryTrendStats: ['avg', 'min', 'med', 'max', 'p(95)', 'p(99)', 'count'], };
デフォルトですと'avg', 'min', 'med', 'max', 'p(95)'
が表示されますが,更に追加で 'p(99)', 'count'
を表示するようにしました.
checks.........................: 100.00% ✓ 1251 ✗ 0 data_received..................: 4.6 MB 51 kB/s data_sent......................: 385 kB 4.3 kB/s ✓ failed requests................: 0.00% ✓ 0 ✗ 1251 http_req_blocked...............: avg=6.38ms min=0s med=1µs max=237.1ms p(95)=33.8ms p(99)=70.11ms count=1251 http_req_connecting............: avg=2.05ms min=0s med=0s max=221.34ms p(95)=9.88ms p(99)=16.56ms count=1251 ✓ http_req_duration..............: avg=88.12ms min=23.63ms med=68.47ms max=1.87s p(95)=151.46ms p(99)=420.5ms count=1251 { expected_response:true }...: avg=88.12ms min=23.63ms med=68.47ms max=1.87s p(95)=151.46ms p(99)=420.5ms count=1251 http_req_failed................: 0.00% ✓ 0 ✗ 1251 http_req_receiving.............: avg=174.17µs min=40µs med=128µs max=21.53ms p(95)=348.5µs p(99)=538µs count=1251 http_req_sending...............: avg=188.65µs min=24µs med=166µs max=973µs p(95)=371µs p(99)=525.5µs count=1251 http_req_tls_handshaking.......: avg=4.19ms min=0s med=0s max=181.1ms p(95)=23.69ms p(99)=35.61ms count=1251 http_req_waiting...............: avg=87.75ms min=23.34ms med=68.05ms max=1.85s p(95)=151.09ms p(99)=420.16ms count=1251 http_reqs......................: 1251 13.89481/s iteration_duration.............: avg=1m28s min=1m27s med=1m28s max=1m29s p(95)=1m29s p(99)=1m29s count=6 iterations.....................: 6 0.066642/s vus............................: 71 min=5 max=99 vus_max........................: 100 min=100 max=100
テストの合格条件を定める
テストの合格条件を自分はこれまで目視でチェックしたり計算していましたが,k6 では合格条件の数値を指定してそれをチェックできます.例えば,次のコードでは k6 の結果で出てくる項目の failed requests
とhttp_req_duration
で合格条件をチェックするようにしています.条件としては次のようなもの意図して設定しています.
- エラー率が1%未満
- レスポンスタイムが99%タイルで500ms以下
export let options = { thresholds: { 'failed requests': ['rate<0.01'], 'http_req_duration': ['p(99)<500'] }, };
関連情報
まとめ
k6 の概要,導入,テスト実行,オプションをの簡単な紹介を記事にまとめました.テストでチェックしたい合格基準の閾値を設定すれば,そのチェックをしてくれたり実際の利用シーンのようなユーザー数の増加も調整できたりと,使ってみてよかったです.本番に乗せる前に API の機能でどれくらいパフォーマンスが出て,目標値に達していそうかがわかるのが良かったので,気になる方は使うきっかけになれば嬉しいです!