DEV Community

Cover image for k6 負荷テスト API実践ガイド
Akira
Akira

Posted on • Originally published at apidog.com

k6 負荷テスト API実践ガイド

APIが1人のユーザーでは問題なく動くのに、トラフィックが増えると遅くなる、失敗する、タイムアウトする。そういう場合はロードテストが必要です。k6を使うと、JavaScriptでシナリオを書き、APIに再現可能な負荷をかけ、レイテンシ、エラーレート、スループットを測定できます。このガイドでは、k6のインストール、最初のスクリプト、VU・ステージ・閾値の設定、結果の読み方、CIでの使い方を実装手順として整理します。API全体の品質管理では、k6による負荷テストを通常のAPIパフォーマンステストの一部として扱い、詳細な仕様は公式のk6ドキュメントも参照してください。

今すぐApidogを試す

k6とは?

k6は、現在Grafanaによって管理されているオープンソースのロードテストツールです。テストシナリオはJavaScriptで書き、k6のGoエンジンがそれを実行して、対象APIへ仮想ユーザーのトラフィックを送ります。

k6の仕組みを示す図。開発者がJavaScriptでスクリプトを書き、それがk6のGoエンジンで実行され、対象のAPIに負荷をかける様子。

k6が得意なのは、持続的で再現性のある負荷を生成し、システムの応答を測定することです。APIクライアント、ドキュメントツール、機能テストフレームワークではありません。ロードエンジンです。

よく使う用語は次のとおりです。

  • Virtual user(VU): スクリプトをループ実行する仮想ユーザー。同時実行数を表します。
  • Iteration(イテレーション): テスト関数を1回実行すること。
  • Stage(ステージ): 時間経過に応じてVU数を増減させる負荷プロファイルのステップ。
  • Threshold(閾値): メトリクスに対する合否条件。例: p(95)<500
  • Check(チェック): レスポンスに対するソフトアサーション。失敗してもテストは継続します。

k6のインストール

k6は単一バイナリとして提供されるため、インストールは簡単です。

macOSでHomebrewを使う場合:

brew install k6
Enter fullscreen mode Exit fullscreen mode

WindowsでChocolateyを使う場合:

choco install k6
Enter fullscreen mode Exit fullscreen mode

DebianまたはUbuntuの場合:

sudo gpg -k
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg \
  --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" \
  | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install k6
Enter fullscreen mode Exit fullscreen mode

インストール後、バージョンを確認します。

k6 version
Enter fullscreen mode Exit fullscreen mode

ローカルにインストールしたくない場合はDockerイメージも利用できます。パッケージやコマンドは更新される可能性があるため、最新の手順はk6公式ドキュメントのインストールページを確認してください。

初めてのk6スクリプト

k6のテストは、default関数をエクスポートするJavaScriptモジュールです。k6は、各VUの各イテレーションでこの関数を実行します。

まず、単一エンドポイントにGETリクエストを送り、ステータスとレスポンス本文を確認する最小スクリプトを作ります。

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

export default function () {
  const res = http.get('https://test-api.example.com/users');

  check(res, {
    'status is 200': (r) => r.status === 200,
    'body is not empty': (r) => r.body.length > 0,
  });

  sleep(1);
}
Enter fullscreen mode Exit fullscreen mode

script.jsとして保存し、実行します。

k6 run script.js
Enter fullscreen mode Exit fullscreen mode

デフォルトでは、k6は1 VUで1イテレーションを実行します。

sleep(1)は、ユーザーが操作間に待つ時間を再現するためのものです。sleepがない場合、VUはネットワークが許す限り高速にループします。スループット上限を調べるには有効ですが、実ユーザーの挙動としては不自然になりやすいです。

check()はソフトアサーションです。失敗しても実行は止まりません。ロードテストでは、高負荷時にどの程度失敗が増えるかを観測したいので、テストを継続してメトリクスを集めます。

VU、ステージ、閾値を設定する

実際のロードテストでは、「何人のユーザーが」「どのくらいの時間」「どのように増減するか」を明示します。これはoptionsで設定します。

固定数のVUを一定時間実行する例:

export const options = {
  vus: 50,
  duration: '30s',
};
Enter fullscreen mode Exit fullscreen mode

これは50人の仮想ユーザーを30秒間実行します。

より実運用に近づけるには、ステージを使って負荷を増加、維持、減少させます。

export const options = {
  stages: [
    { duration: '1m', target: 100 },  // 100 VUまで増加
    { duration: '3m', target: 100 },  // 100 VUを維持
    { duration: '1m', target: 0 },    // 0 VUまで減少
  ],
  thresholds: {
    http_req_duration: ['p(95)<500'], // リクエストの95%が500ms未満
    http_req_failed: ['rate<0.01'],   // エラー率が1%未満
  },
};
Enter fullscreen mode Exit fullscreen mode

閾値はCIで特に重要です。閾値に失敗すると、k6は非ゼロの終了コードで終了します。つまり、p95レイテンシやエラーレートが許容値を超えた場合に、CIパイプラインでビルドを失敗させられます。

機能テストでアサーションを書くのと同じように、パフォーマンス予算をコードとして管理できます。

代表的なロードプロファイルは次のとおりです。

プロファイル 目的 何がわかるか
スモーク ごく小さい負荷でスクリプトの動作を検証する テスト自体が正しいか
ロード 通常想定されるトラフィックを再現する 日常的な負荷に耐えられるか
ストレス 想定ピークを超える負荷をかける どこで破綻し始めるか
スパイク 短時間でVUを急増させる 急激なトラフィック増加に耐えられるか
ソーク 中程度の負荷を長時間かける メモリリークや徐々に悪化する性能劣化があるか

最初からすべてを実施する必要はありません。まずはスモークテストと通常のロードテストから始め、基準値が見えたらストレス、スパイク、ソークを追加します。

より広い考え方やメトリクスについては、パフォーマンステストの基礎も参考になります。

k6の結果を読む

実行が終わると、k6はターミナルにサマリーを出力します。まず見るべきメトリクスは次のとおりです。

  • http_req_duration: リクエスト全体の所要時間。平均、最小、最大、中央値、p90、p95などで表示されます。
  • http_req_failed: 失敗したリクエストの割合。
  • http_reqs: 総リクエスト数と1秒あたりのリクエスト数。スループットを示します。
  • iterations: 完了したイテレーション数とレート。
  • vus / vus_max: 実行中のVU数と最大VU数。
  • checks: check()アサーションの成功率。

平均値だけで判断しないでください。平均応答時間が200msでも、p99が4秒なら、100人に1人は4秒待っていることになります。ユーザー体験の悪化は、平均ではなくテールレイテンシに現れます。

継続的に分析したい場合は、k6の結果をJSONやCSVに出力したり、GrafanaやPrometheusと連携したりできます。単発の検証ならターミナルサマリーで十分ですが、継続的な監視では時系列でグラフ化できる場所にメトリクスを送る方が実用的です。

k6とApidogの使い分け

k6はロードエンジンです。答える問いは「持続的なトラフィック下でAPIはどう振る舞うか」です。

一方で、APIが正しいデータを返すか、契約に合っているか、認証が期待通りに動くかは、機能テストや契約テストの領域です。ここは別のツールで扱うべきです。

関心事 適したツール 答える問い
持続的な高負荷、レイテンシのパーセンタイル k6 トラフィック下でも高速に動くか
機能的な正確性、契約、認証 Apidog 正しいレスポンスを返すか
CIでのコミットごとのリグレッション検出 Apidog (apidog run) この変更でAPIが壊れていないか
CIでのパフォーマンス予算 k6の閾値 レイテンシやエラー率が許容値を超えたか

Apidogは、APIの正確性を扱うためのツールです。APIを設計またはインポートし、テストシナリオを作成し、apidog runCI上から実行できます。Apidog CLIガイドでは、機能テストをパイプラインに組み込む方法を説明しています。

Apidogには簡単なチェック向けの軽量なパフォーマンステスト機能もあり、ApidogでのAPIパフォーマンステストで紹介されています。ただし、k6のような専用ロードジェネレーターとは役割が異なります。

実用的なワークフローは次のようになります。

  1. コミットごとにApidogで機能テストと契約テストを実行する。
  2. リリース前または定期スケジュールで、k6をステージング環境に対して実行する。
  3. Apidogで正確性を確認し、k6で負荷耐性を確認する。
  4. どちらかが失敗したら、CIを失敗させる。

ロードテストツールを比較している場合、k6はJMeter、Gatling、Locustと並ぶ選択肢です。ロードテストツール比較Locust代替比較では、スクリプト言語やスケールによるトレードオフを確認できます。

よくある質問

k6は無料ですか?

はい。k6はAGPLライセンスのオープンソースであり、ローカルではハードウェアの制約内で自由に実行できます。

Grafanaはk6 Cloudも提供しています。これは大規模な分散テストや結果保存のための有料サービスですが、k6を使うために必須ではありません。まず無料の選択肢を比較したい場合は、ロードテストツールの概要を確認してください。

k6を使うにはJavaScriptの知識が必要ですか?

基本的なJavaScriptが必要です。ただし、深い専門知識は不要です。多くのk6スクリプトは、次の要素で構成されます。

  • default関数
  • http.get()またはhttp.post()
  • check()
  • sleep()
  • options

このガイドのコードが読めれば、実用的なテストを書き始められます。

k6とApidogのパフォーマンステストの違いは何ですか?

k6は、持続的な高負荷を生成し、p95やp99などの大規模なパーセンタイルを測定する専用ロードジェネレーターです。

Apidogは、API設計、機能テスト、契約テストに重点を置いたAPIプラットフォームで、簡単な確認向けの軽量なパフォーマンステスト機能も備えています。

実際の負荷テストとCI上のパフォーマンス予算にはk6を使い、正確性、契約検証、コミットごとの機能テストにはApidogを使うのが実用的です。

k6をCI/CDで実行できますか?

はい。k6はCI/CDでよく使われます。

閾値に失敗すると非ゼロの終了コードで終了するため、どのCIシステムでもパフォーマンスリグレッションを検出できます。

例:

k6 run script.js
Enter fullscreen mode Exit fullscreen mode

実運用では、次のように設定します。

  • ステージング環境を対象にする
  • p95レイテンシの閾値を設定する
  • エラーレートの閾値を設定する
  • apidog runの機能テストと組み合わせる

これにより、各変更に対して「APIが正しいか」と「負荷下でも許容範囲内か」の両方を確認できます。

まとめ

k6を使うと、APIに再現可能な負荷をかけ、レイテンシ、エラーレート、スループットを測定できます。基本の流れは次のとおりです。

  1. k6をインストールする。
  2. JavaScriptでテストシナリオを書く。
  3. VU、ステージ、閾値を設定する。
  4. k6 runで実行する。
  5. 平均ではなくp95やp99を読む。
  6. CIで閾値を使って失敗条件をコード化する。

ロードテストと機能テストは別の問いに答えます。k6で負荷下の性能を測定し、ApidogでAPIの設計、テスト、モック、ドキュメント化、CIでの機能テストを管理すると、正確性と性能の両方を継続的に確認できます。

Top comments (0)