オープンソースの負荷テストツールのk6に入門

2022.02.15

カオスカーニバルというイベントにてカオスエンジニアリングの実験を実行するときに利用できる負荷ツールを教えてもらったので試してみようと思います。

k6という名前の負荷テストツールで、オープンソース、無料、開発者中心、拡張可能です。

開発者向けの使いやすいAPIとCLIを備えていて、パフォーマンステストを自動化するために設計されています。

ユースケースとしては、

  • 負荷テスト
    • リソース消費を最小限に抑えるように最適化されており、高負荷テスト(スパイク、ストレス、ソークテスト)を実行するように設計されています
  • パフォーマンスと総合的なモニタリング
    • 少量の負荷でテストを実行して、実稼働環境のパフォーマンスと可用性を継続的に検証できます
  • カオスと信頼性のテスト
    • カオス実験の一部としてトラフィックをシミュレートしたり、k6のテストからトラフィックをトリガーすることができます

といったものが挙げられています。

今回はオープンソースのk6をインストールし、使用方法を確認していきたいと思います。

k6のインストール

インストール方法のページから、各環境ごとにパッケージマネージャーからインストールするか、 リリースページからk6バイナリをダウンロードします。

Macの場合)

brew install k6

k6の実行

実行にはスクリプトを記述する必要があり、スクリプトはJavaScriptのES6モジュールとして記述します。 k6では、スクリプトを実行する仮想ユーザー(VU)というコンセプトで動作しています(並列数)。

以下のように、最低でもdefalut関数をエクスポートする必要があります。

import http from 'k6/http';
import { sleep } from 'k6';

export default function () {
  http.get('https://test.k6.io');
  sleep(1);
}

では、このコードをシステム上に保存して,以下のコマンドで実行してきます。

script.jsという名前で保存している場合)

k6 run script.js

実行すると、上記のように結果が表示されます。

スクリプトのライフサイクルステージ

最低でもdefalut関数をエクスポートする必要があります と書かれていますが、

defaultの部分がVU codeと呼ばれており、テストが実行されている限り何度も実行される箇所です。

k6では以下のように4つのステージに分類されています。

// 1. init code

export function setup() {
  // 2. setup code
}

export default function (data) {
  // 3. VU code
}

export function teardown(data) {
  // 4. teardown code
}

1. init codeではローカルファイルシステムからロードしたり、他のモジュールをインポートしたりします。

2. setup code, 4. teardown codeは、他の多くのテストフレームワークやツールと同様に、テスト全体のセットアップとティアダウンを実行します。

setup()はテストの最初、initステージの後、VU ステージ(デフォルト関数)の前に呼ばれ、teardown()はテストの最後、最後のVUイテレーション(デフォルト関数)の実行が終了した後に呼ばれます。

setup()が返すデータのコピーは、デフォルト関数の各反復処理とテスト終了時のteardown()の最初の引数として渡される とのことです。

例)

export function setup() {
    return {v: 1};
}

export default function(data) {
    console.log(JSON.stringify(data));
}

export function teardown(data) {
    if (data.v != 1) {
        throw new Error("incorrect data: " + JSON.stringify(data));
    }
}

上記を実行すると、

setup()で設定したjsonのデータがdefaultで参照できていることがわかりました。

結果の出力内容

k6 run を実行した後に表示される内容ですが、デフォルトでは集計された要約レポートが表示されます。

このように、k6ロゴと次のテスト情報が表示されます。

  • テストの詳細
    • 一般的なテスト情報とロードオプション。
  • プログレスバー
    • テストステータスと経過時間。
  • テストの概要
    • テスト結果(テスト完了後)。k6 v0.30.0以降、出力を完全にカスタマイズしてファイルにリダイレクトすることが可能です。また、JSON、XML(JUnit、XUnitなど)、または人間向けの適切にフォーマットされたHTMLレポートなど、機械可読バージョンの要約を使用して任意のファイルを保存することもできます。

この内容はカスタマイズが可能※1だったり、外部出力(InfluxDB、Kafka、StatsDなど)にストリーミングすることもサポートしているとのことですが、本記事では割愛します。

※1 レポートのカスタマイズについて

テストの詳細

execution: local
     script: script01.js
     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)

executionはk6の実行モードです(localかcloud)。

scriptは実行したスクリプトのファイル名です。

outputに詳細なテスト結果が出力されますが、デフォルトでは出力※2は使用されず、集計されたテスト終了の要約のみが表示されます

※2 外部出力

scenariosは、テスト実行で実行されるシナリオの要約といくつかの概要情報が表示されます。

シナリオに関しては別記事にて試してみようと思いますので、ここでは割愛します。

要約レポート

running (00m02.1s), 0/1 VUs, 1 complete and 0 interrupted iterations
default ✓ [======================================] 1 VUs  00m02.1s/10m0s  1/1 iters, 1 per VU

     data_received..................: 17 kB 7.9 kB/s
     data_sent......................: 511 B 240 B/s
     http_req_blocked...............: avg=944.57ms min=944.57ms med=944.57ms max=944.57ms p(90)=944.57ms p(95)=944.57ms
     http_req_connecting............: avg=181.34ms min=181.34ms med=181.34ms max=181.34ms p(90)=181.34ms p(95)=181.34ms
     http_req_duration..............: avg=184.88ms min=184.88ms med=184.88ms max=184.88ms p(90)=184.88ms p(95)=184.88ms
       { expected_response:true }...: avg=184.88ms min=184.88ms med=184.88ms max=184.88ms p(90)=184.88ms p(95)=184.88ms
     http_req_failed................: 0.00% ✓ 0        ✗ 1
     http_req_receiving.............: avg=559µs    min=559µs    med=559µs    max=559µs    p(90)=559µs    p(95)=559µs
     http_req_sending...............: avg=986µs    min=986µs    med=986µs    max=986µs    p(90)=986µs    p(95)=986µs
     http_req_tls_handshaking.......: avg=585.41ms min=585.41ms med=585.41ms max=585.41ms p(90)=585.41ms p(95)=585.41ms
     http_req_waiting...............: avg=183.33ms min=183.33ms med=183.33ms max=183.33ms p(90)=183.33ms p(95)=183.33ms
     http_reqs......................: 1     0.469061/s
     iteration_duration.............: avg=2.13s    min=2.13s    med=2.13s    max=2.13s    p(90)=2.13s    p(95)=2.13s
     iterations.....................: 1     0.469061/s
     vus............................: 1     min=1      max=1
     vus_max........................: 1     min=1      max=1

デフォルトでは

  • 組み込みメトリックとカスタムメトリックの集計値
  • チェックとしきい値
  • グループとタグ

が出力されるようです。

メトリックスに関しては以下のドキュメントに詳しく書かれています。

さいご

負荷テストツールのk6をローカルマシンにインストールして実行するところまで試してみました。

負荷テストの内容をコードで記述していくことからもみてとれますが、開発者のために構築されたツールになります。 拡張も可能で、大規模なテストでも小規模なテストでも使用でき、外部のデータベースや監視ツールなんかにもメトリクスを出力できるので使い勝手は良さそうですね。

参考