k6
golang製の負荷試験ツール k6を一言で言うとJSで書けるツールになっており、ユニットテストみたいに性能テストすることを目指しいるOSS。
k6 ユビキタス
--vus : 並列数 --duration : 期間 thresholds : 閾値
k6仕組み
K6は Javascript
を用いて負荷試験のテストを実施するががGolangの内部でECMAScript 2015+(ES6+)を実行している。
K6はNode.jsでも、ブラウザーでもなく、Node.jsによって提供されるAPIに依存するパッケージ、たとえばosとfsモジュールはK6では機能しない。
その為、データ加工などのモジュールを提供しているのがこれらです。
データ加工モジュール
Headless Browser を使ったブラウザテスト
Playwright API互換を目指しているようですが、K6内での動きはそれと異なる場合があります。 これはK6がNode.jsの上で動いていないかつ、イベントループをサポートしていないためです。
k6 jslib
まず、K6には k6 jslib
というK6の拡張ツール等がある。
参考URL
k6-jslibはawsなどがあるがgcp版はない
内容の見方
ライフサイクル
最低でもdefault関数をエクスポートする必要がある。
default
の部分が VU code
と呼ばれておりテストが実行されている限り何度も実行される箇所。
// 1. init code
export function setup() {
// 2. setup code
}
export default function (data) {
// 3. VU code
}
export function teardown(data) {
// 4. teardown code
}
-
init codeではローカルファイルシステムからロードしたり、他のモジュールをインポートしたりします。
-
setup code, 4. teardown codeは、他の多くのテストフレームワークやツールと同様に、テスト全体のセットアップとティアダウンを実行します。
setup()はテストの最初、initステージの後、VUステージ(デフォルト関数)の前に呼ばれ、teardown()はテストの最後、最後のVUイテレーション(デフォルト関 数)の実行が終了した後に呼ばれます。
setup()が返すデータのコピーは、デフォルト関数の各反復処理とテスト終了時のteardown()の最初の引数として渡される とのことです。
負荷
K6は1つのインスタンスで30万リクエストかけられると謳っており、 他テストツールと比べて非常に高パフォーマンスらしいです。
外部出力
この内容はカスタマイズが可能※1だったり、外部出力(InfluxDB、Kafka、StatsDなど)にストリーミングすることもサポートしているとのことですが、本記事では割愛します。
サンプルファイル
CI/CDで実行する意義
CLIに出力された内容(早見表)
data_received レスポンスデータ量(Total, /s)
data_sent リクエエストデータ量(Total, /s)
http_req_blocked TCP接続の順番待ちをした時間(avg, min, med, max, p(90), p(95)
http_req_connecting TCP接続にかかった時間(avg, min, med, max, p(90), p(95)
http_req_duration http_req_sending + http_req_waiting + http_req_receiveing(avg, min, med, max, p(90), p(95)
expected_response 正常応答のみのhttp_req_duration(avg, min, med, max, p(90), p(95)。正常な応答がない場合、この項目は表示されない
http_req_failed リクエストが失敗した割合(%)
http_req_receiving レスポンスの1バイト目が到達してから最後のバイトを受信するまでの時間(avg, min, med, max, p(90), p(95)
http_req_sending リクエストを送信するのにかかった時間(avg, min, med, max, p(90), p(95)
http_req_tls_handshaking TLSセッションのハンドシェイクにかかった時間(avg, min, med, max, p(90), p(95)。httpでは0
http_req_waiting リクエストが送信完了してから、レスポンスが開始されるまでの時間(avg, min, med, max, p(90), p(95)
TTFB(Time To First Byte) 参考URL 合格ラインは0.6秒 TTFBとは「最初の1バイトを受信するまでの時間」(Time To First Byte)を意味する。
http_reqs リクエスト総数。(Total, /s)
iteration_duration シナリオ1ループにかかった時間(avg, min, med, max, p(90), p(95)。
iterations シナリオを繰り返した回数(Total, /s)
vus Virtual UserS 最後のシナリオのときの並列数
vus_max 最大Virtual UserS テスト中の最大並列数
ここからはオプション
localで実行した時のosチューニング
GNU/Linux、BSD、macOS などの Unix オペレーティング システムの派生製品には、システムの安定性を確保するために、プロセスが使用できるシステム リソースの量を制限する機能があります。これには、1 つのプロセスが管理できるメモリの総量、CPU 時間、または 開いているファイルの量が含まれます。 Unix では、ネットワーク接続を含むすべてがファイルであるため、k6 などのネットワークを頻繁に使用するアプリケーション テスト ツールは、特定のテストで使用されるネットワーク接続の量に応じて、許可されている開いているファイルの構成された制限に達する可能性があります。
k6 CLIメトリクス 説明
k6 コードロジック
iteration_duration を計算するための回避策
Datadogと連携する
grafanaで見る
grafana inflaxdbと連携するように リファレンス
ファイr
export const options: Options = {
// thresholds,
maxRedirects: 0,
scenarios: {
constant_request_rate: {
executor: "constant-arrival-rate",
rate: 1000,
timeUnit: "1s", // 1000 iterations per second, i.e. 1000 RPS
duration: "5m",
preAllocatedVUs: 100, // how large the initial pool of VUs would be
maxVUs: 200, // if the preAllocatedVUs are not enough, we can initialize more
},
},
};
export default function (): void {
// `VU コード」と呼ばれ、テストの実行中に何度も繰り返されます。その外側のコードは「初期化コード」と呼ばれ、各 VU に対して 1 回だけ実行されます。 `
const SLEEP_TIME_SECOND = 1;
const username = "parrot-stg";
const password =
"dmZo4oVkTw01BamvdzJGPH17w1PXbzEO27t7LWqXVMMQSnsdheCrf5L9JtyX65DS";
const credentials = `${username}:${password}`;
{
const path = `https://${credentials}@stg.parrot.nijisanji.jp`;
checkResponse(http.get(path));
sleep(SLEEP_TIME_SECOND);
}
}