COLOPL Tech Blog

コロプラのエンジニアブログです

k6 + Cursor の負荷試験がとても手軽だった件

こんにちは、バックエンドエンジニアの岡村です。

新サービス「FANPARK」をリリースするにあたり、負荷試験を実施しました。今回は負荷試験ツールとしてk6を採用し、その手軽さに驚いたので、この経験を共有させていただきます。特に、AIエージェント(Cursor)がほとんどの作業を代行してくれたことで、負荷試験の実施が非常にスムーズに進みました。

背景

「FANPARK」は、位置ゲーのノウハウを活用してライブの待ち時間を遊び時間に変える新サービスです。10月に開催されたファッションと音楽が交差するスペシャルイベント「ZOZOFES」に導入しました。会場であるKアリーナは2万人のキャパシティを有しており、来場が一番多くなるのは開場時間周辺ということで、それなりの負荷が予想される状況でした。

今回のサービスはWebサービスとして実装しており、フロントエンド側はNext.js、バックエンドはLaravelで構築されています。ゲームタイトルの負荷試験を行う際は、弊社のゲーム基盤に最適化された内製ツール(Go言語)を使用していますが、今回は比較的シンプルなWebサービスであるため、より一般的な負荷試験ツールでの実施を検討しました。

k6について簡単な説明

k6は、JavaScriptスクリプトを記述できる軽量な負荷試験ツールです。データ可視化ツールでお馴染みのGrafana Labsが開発とメンテナンスを行っています。従来の負荷試験ツールと比較して、以下の特徴があります。

k6を選んだ理由

負荷試験ツールの選定において、次の理由からk6を選択しました。

これらの理由から、k6が今回の負荷試験に最適なツールであると判断しました。

k6の導入と設定

インストール

k6のインストールは非常にシンプルでした。macOS + Homebrew 環境では以下のコマンドだけでインストールできます

brew install k6

テストスクリプトの作成

まずはドキュメント通りに雛形を作成し、簡単なシナリオをCursorに書いてもらいました。

# scenario.jsという名前で雛形を作成
k6 new scenario.js

実際に作成したk6スクリプトの例を以下に示します。

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

export let options = {
  vus: 1, // 1ユーザーで実行
  duration: '30s', // 30秒間実行
};

export default function () {
  // ユーザー登録APIの呼び出し
  let response = http.post('https://api.example.com/user/register', {
    name: 'Test User',
    email: `test${Math.random()}@example.com`,
  });

  check(response, {
    'status is 200': (r) => r.status === 200,
    'response time < 500ms': (r) => r.timings.duration < 500,
  });

  sleep(1);
}

シナリオの作成

雛形での動作確認が済んだ後は、下記の流れでシナリオを作成しました。

  1. フロントエンド側に実装していた通信基盤周りのコード流用し、Cursorに「k6負荷試験をしたいので書き換えて」と指示
  2. バックエンド側にE2Eテストを実装していたため、Cursorに「テスト参考にk6の形式でシナリオを書いて」と指示
  3. その後、生成されたコードを見渡して細かい調整をする

AIがサクサクと実装を進めてくれたおかげで、初めて触るk6でもつまづくことがなく非常に助かりました。k6のモジュール(通信部分などにはk6/httpなど)を使用してシナリオを書く必要がありますが、AIがいい感じに実装してくれました。比較的馴染みのあるJavaScriptの実装という点もあり、個人的には生成結果を読みやすかったのも良かったです。

負荷試験の実施

負荷パターン

負荷試験は段階的に実施しました。

  1. 初めは簡単なシナリオ、1ユーザーでのシナリオ、次に50人でのシナリオを試す
  2. その後、50人の負荷を5分間、その後100人の負荷を5分間、最後に200人の負荷を5分間、というように段階的に負荷を上げていくシナリオを作成
  3. 段階的に負荷を本番想定にしていく

結果と発見

負荷試験の結果、以下のようなことが分かりました。

  • 特別な環境を用意することなく、ローカルPCでも十分な内容の負荷試験を実施できた
  • 負荷試験の結果をいい感じにまとめてくれる
    • そのままAIに投げれば要約してくれるので、認知負荷が低い
    • 次にすべきこともAIが提案してくれる
  • 時系列のグラフも出力する設定もあって便利
    • Cloud RunやCloud SQLのメトリクスを見れば間に合うので、今回は本格的には使用しなかった

k6負荷試験では以下のような詳細な指標が自動的に出力されます。 これらの指標から、レスポンス時間の分布、スループット、エラー率などが一目で分かります。

# 負荷試験の実行
k6 run scenario.js

         /\      Grafana   /‾‾/
    /\  /  \     |\  __   /  /
   /  \/    \    | |/ /  /   ‾‾\
  /          \   |   (  |  ()  |
 / __________ \  |_|\_\  \_____/

     execution: local
        script: scenario.js
        output: -

     scenarios: (100.00%) 1 scenario, 10 max VUs, 1m0s max duration (incl. graceful stop):
              * default: 10 looping VUs for 30s (gracefulStop: 30s)



  █ TOTAL RESULTS

    HTTP
    http_req_duration..............: avg=171.56ms min=166.75ms med=171.36ms max=181.49ms p(90)=174.05ms p(95)=174.91ms
      { expected_response:true }...: avg=171.56ms min=166.75ms med=171.36ms max=181.49ms p(90)=174.05ms p(95)=174.91ms
    http_req_failed................: 0.00%  0 out of 250
    http_reqs......................: 250    8.243623/s

    EXECUTION
    iteration_duration.............: avg=1.21s    min=1.16s    med=1.17s    max=2.11s    p(90)=1.17s    p(95)=1.18s
    iterations.....................: 250    8.243623/s
    vus............................: 10     min=10       max=10
    vus_max........................: 10     min=10       max=10

    NETWORK
    data_received..................: 850 kB 28 kB/s
    data_sent......................: 19 kB  609 B/s




running (0m30.3s), 00/10 VUs, 250 complete and 0 interrupted iterations
default ✓ [======================================] 10 VUs  30s

注意点

負荷試験の実施において、以下の点に注意が必要でした。

  • AIに閾値設定を任せると、想定より緩い設定になる場合があるため注意が必要
    • 例えば、latency 5s (めっちゃ遅い!) を許容する設定を提案されることがありました
  • AIが生成したコードや試験結果の要約は、正しさを検証しつつ利用する必要
    • 生成されたコードはブラックボックスとして扱うのでなく、動作原理をなるべく理解しましょう
    • 試験結果はインスタンス側のメトリクスを見るなどし、多角的に正しい負荷をかけられていることを確認しましょう

AIエージェント駆動開発の効果

k6とAIエージェント(Cursor)を組み合わせることで、負荷試験の実施が格段に効率化されました。

従来の負荷試験ツール導入では、新しいツールの仕様やAPIを理解する時間、ゼロからテストスクリプトを書く時間、エラー修正や動作確認の時間、そして出力された数値の解釈と改善点の特定など、多くの工程が必要でした。

今回のAIエージェント活用では、これらの工程が効率的に短縮されました。k6の詳細な仕様を覚える必要がなく、AIがk6の構文に準拠したコードを生成してくれます。既存のE2Eテストを参考に、数分でk6スクリプトを生成でき、エラー発生時もAIが原因と解決策を提案してくれます。負荷試験結果の要約と改善提案も自動化され、開発効率が格段に向上しました。

ただし、 AIエージェントのことを100%信じるのは危険です。 あくまで最短距離へ導くためのツールとして使うのにはとても良いツールですが、生成されたコードや提案された設定は必ず検証が必要です。AIエージェントはk6のことを上手に生成できるようなので、そのような使い方に合っているように感じました。

おわりに

今後のWebサービス開発でも、要件に応じてk6での負荷試験を積極的に検討していきたいと考えています。

k6負荷試験ツールとして非常に手軽で、特にJavaScriptで書ける点とAIとの相性の良さが印象的でした。シュッと試験したい際にはとても有用なツールだと思います。

より複雑なサービスでの活用については今後検証していきたいと考えています。

今後もk6を活用して、より良いサービスを提供していきたいと思います。



ColoplTechについて

コロプラでは、勉強会やブログを通じてエンジニアの方々に役立つ技術や取り組みを幅広く発信していきます。
connpass および X で情報発信していますので、是非メンバー登録とフォローをよろしくお願いいたします。

また、コロプラではゲームや基盤開発のバックエンド・インフラエンジニアを積極採用中です!
興味を持っていただいた方はぜひお気軽にご連絡ください。