Argo WorkflowsとGatlingで作るスケーラブルな負荷テスト環境

これはアソビュー! Advent Calendar 2023の1日目です🎄 今年のアドベントカレンダーは2面公開なので、ぜひそちらも御覧ください!

アソビューでVPoE兼Tech Leadをしているdisc99🐼です!
今回はアソビューの負荷テスト環境の事例を紹介させてもらえればと思います!

はじめに

多くのサービスは実際の運用環境において予期せぬトラフィックやアクセスパターンに直面します。

サービスのパフォーマンス、スケーラビリティ、安定性を評価するために負荷テストは重要で、実際のトラフィックを模倣し、サービスが指定された要件を満たすかどうかを評価することで、サービスの設計や構成にフィードバックできます。

弊社が提供するサービスの中でも特にtoC向けである、遊びの予約サイト「アソビュー!」やチケット直販サービスである「ウラカタチケット」などではピーク時には数千rpsのアクセスが発生したり、時間や時期によって大きくアクセス特性が異なってきます。

このような状況の中で安定してサービスを提供するために負荷テストは重要な役割を果たしています。

負荷テストに求められるもの

負荷テストには、サービスのパフォーマンスを正確に測定し、現実世界のシナリオを再現できる能力が求められます。
また、大量のトラフィックを再現する性質上、クライアント側のリソースやネットワーク帯域が十分な環境でないと、必要となるトラフィックが再現できなくなります。

小規模なサービスであればローカルマシン上でシナリオを実行するだけ十分な場合もありますが、大規模なトラフィックや長時間のストレステストなどを実行する場合には、これらを満たすのは難しくなります。
実際のシナリオを再現させ、大量のトラフィックを実現するには、クライアントのスケーラビリティが重要となります。

このような要件を満たすために、アソビューではAWSのAmazon EKS上でArgo WorkflowsとGatlingを利用した負荷テストの環境を構築しています。

現在、負荷テスト環境を実現するソリューションは多数ありますが、元々社内的にワークフローエンジンとしてArgo Workflowsを利用しており、Gatlingを利用した負荷テストの実績もあったため、これらの環境を活かす形で負荷テスト環境を構築し2年程度運用をしています。

Argo Workflowsとは

argoproj.github.io

Argo Workflowsは、Kubernetes上で複雑なジョブとワークフローをオーケストレーションするためのワークフローエンジンで以下のような特徴を持っています。

  1. Kubernetesネイティブ
    Argo WorkflowsはKubernetes APIを利用し、Kubernetesクラスター上で直接動作します。
    これにより、Kubernetesの機能とシームレスに統合し、スケーリングや管理が容易になります。

  2. 柔軟なワークフロー定義
    ワークフローはYAMLファイルで定義され、ステップや依存関係を記述します。これにより、複雑なタスクのシーケンスを簡単に管理できます。
    また、DAGやパラメーター、アーティファクト、条件分岐など柔軟なワークフローを構築する機能が揃っています。

  3. ユーザーインターフェース
    Argo WorkflowsにはウェブベースのUIがあり、ワークフローの状態をリアルタイムで視覚化し、管理することができます。

こういった特徴の中でも、負荷テストに必要となるスケーラビリティなどを用意に実現することができるため、実行環境として選択しました。

また、アソビューで利用しているAmazon EKSでは、ワーカーノードとしてAmazon EC2とAWS Fargateをサポートしており、現在の負荷テスト環境ではAWS Fargateを利用しています。

Gatlingとは

gatling.io

Gatlingは、高性能な負荷テストツールで以下のような特徴を持っています。

  1. スクリプトベース
    テストシナリオをScalaを使ったDSLのスクリプトとして記述できます。
    これにより、テストシナリオを柔軟かつ簡潔に記述できます。
    Scalaのコードで記述できるため、条件分岐や外部からデータのIDなど、必要に応じカスタマイズされたテストケースを作成できます。
    また、コードで定義されているため、ソースコード管理ツールとの相性もよく、変更履歴などを随時確認することもできます。

  2. リアルタイムモニタリング
    テスト実行中にリアルタイムでパフォーマンスデータを収集し、グラフィカルなダッシュボードやレポートを提供します。
    これにより、テスト中に問題を検出し、性能のボトルネックを素早く特定できます。

  3. ユーザーシミュレーション
    数千から数十万の仮想ユーザーをシミュレートできます。
    これにより、アプリケーションが実際のトラフィックに耐えられるかどうかをテストできます。
    さらに、異なるユーザーシナリオや負荷条件をシミュレートすることで、アプリケーションの振る舞いを多角的に評価できます。

  4. シナリオのモジュール化
    シナリオのモジュール化をサポートしており、共通のアクションやステップを再利用可能なコンポーネントとして定義し、シナリオ間で共有できます。
    これにより、テストスクリプトの保守性が向上し、重複コードを軽減できます。

  5. 複数のプロトコルのサポート
    HTTP、WebSocket、JMS、SMTPなどさまざまなプロトコルをサポートしています。
    アプリケーションやサービスに合わせて適切なプロトコルを選択し、パフォーマンステストを実行できます。

  6. 簡単なセットアップとスケーラビリティ
    Gatlingのセットアップは比較的簡単で、必要な依存関係を解決するのは容易です。
    また、テストの分散実行をサポートしており、複数のマシンでテストを実行して負荷を増やすことができます。
    これにより、大規模な負荷テストを実施できます。

  7. CI/CD統合とコマンドラインインターフェース
    Gatlingはコマンドラインベースのツールであり、CI/CDパイプラインに簡単に統合できます。
    パイプラインに組み込むことで、自動化されたパフォーマンステストを実行して問題を検出し、品質を確保することもできます。

こういった特徴の中でもスケーラビリティやコマンドラインからの実行など、Argo Workflowsと相性が良いため組み合わせて利用しています。

システム構成

全体的なシステム構成は以下になります。

システム構成
GatlingのテストシナリオはGithub上で管理されていて、CIをトリガーにECRに登録されます。 Argo Workflowsではそのシナリオを含んだGatlingのDocker ImageをPullし、テストを実行します。
Argo WorkflowsのJobは大きく、「セットアップ」、「テスト実行」、「テスト結果の集約」のフローに分割したDAGで構成されています。

「セットアップ」: テスト実行時に使う共通的にな、パラメーターの設定などを行います。
「テスト実行」: ワークフローの実行時や「セットアップ」から渡されたパラメーターなどを元に、実際のテストシナリオ実行を行います。
「テスト結果の集約」: 分散して実行された「テスト実行」の実行結果を集約し、S3にレポートファイルをアップロードします。

負荷テストのワークフロー

ワークフローの起動時には、実行するテストシナリオや全体でアクセスするユーザー数や実行時間、分散実行する並列数などの変動要素をパラメーターで指定します。
Argo Workflowを用いることで、「テスト実行」をするJobを手軽に分散実行できます。

Amazon EKSであればJobの実行環境をAWS Fargateを用いることでGatlingのスクリプトを実行するインスタンスを並列数に応じて独立して立ち上げることが可能で、クライアントから大量のトラフィックを送る必要があるときに問題になる、リソース不足やトラフィックの帯域制限を回避することもできます。

また、Gatlingではテスト結果はデフォルトだと確認しやすいHTML形式で出力してくれますが、オプションでlogファイル形式で出力することもでき、今回のように分散実行する場合には、logファイルを出力してすべての結果をマージして最終的なHTML形式に出力することもできます。

HTML形式なのでS3に保存したファイルはダウンロードして確認するだけでなく、Web上で確認することも可能です。

この他に実際の運用では、実行結果だけではなくボトルネックとなっている箇所の特定はエラーログの解析などより深ぼった分析が必要となるため、DatadogのメトリクスやAPM等を利用したダッシュボード、ログなどを組み合わせて確認しています。

運用事例

実際にアソビューでこれらの環境を利用し、どのように負荷テストを実施しているか簡単に紹介します。

テストシナリオの作成と計画

負荷テストの計画時には、テストシナリオの作成を行います。

アソビューの場合、サイトの商品検索や閲覧、予約や購入、購入内容の確認や現地での催行や着券などを主にユーザーが利用する導線を想定しテストシナリオを作成します。
更にシナリオ上同じ導線だったとしても、内部でロジックが大きく異なっていたり、外部のサービス呼び出しの有無などパターンがある場合には、それらを別シナリオとして用意したりもします。

過去に同様のテストを実施している場合は、新規作成は不要ですが、微調整や必要なテストデータの用意なども行います。

また、 テストシナリオの設計には、実際のトラフィックパターンやユーザー行動の分析が重要です。
これらに関しては、GAやサーバー上のメトリクス、ログなどを用いて、実際に来ていたリクエスト数、その時のサーバー上のリソース状況などを元に予測を立てて、現実値に近いテスト条件を導き出します。
条件がまとまり次第、サーバーのスペックアップやデータ投入などを条件に合わせ実施します。

負荷テスト実施とモニタリング

負荷テスト実施に関しては、Argo Workflowsの画面からワークフローに必要なパラメーターを指定し、実行するだけです。

アソビューでは、モニタリングとしてDatadogを利用しているため、Gatlingのレポートだけでは判断できない情報を、実行中や実行後Datadogから確認するようにしています。
Datadogには豊富なモニタリング機能が揃っているので、サービスが不安定になっているときにアプリケーションの状態やログの状態を紐づけて確認したり、分散トレーシングを用いてどのアプリケーションがボトルネックになっているかの洗い出しを行います。

テスト結果の分析とパフォーマンスの改善点

負荷テストの実施後は、収集したデータを詳細に分析します。

この分析により、システムのパフォーマンス上の問題点や改善の余地が明らかになります。
実施してきた例を上げると、インフラやアプリケーショのスケーラビリティ調整、DBやアプリケーションのチューニング、キャッシュ/CDNなどの活用、サーキットブレイカーの設置、入場制限の導入、システム構成やアーキテクチャの見直しなど多岐にわたります。

これらはテストの分析結果から、パフォーマンスを改善するための具体的なアクションプランを洗い出し、優先度判断を行って実施してきました。

ナレッジの蓄積

負荷テストの結果ですが、次回以降実施する際の計画やパフォーマンスの変化を確認する上で重要になります。

Gatlingが生成したレポートファイルはS3上に保存されますが、サーバーのスペックやモニタリングの状況などそれ以外の情報に関してはGitのコミット履歴やDatadogなど様々な環境に保存されるため、後から確認する場合に一覧性がよくありません。

アソビューでは、このような履歴に関して後から追えるように、スプレッドシートやWikiなどにまとめ確認できるようにしています。

まとめ

今回はアソビューで利用しているArgo WorkflowsとGatlingを組み合わせた負荷テスト環境を紹介しました。
この組み合わせにより、大規模なサービスでもスケーラブルに負荷テストを実施することが可能になり、実際の負荷によるサービスの状態を分析から対策まで容易に検討することができます。

現在アソビューでは、ステージング環境を利用して負荷テストを実施していますが、本番環境とリソースのスペックが異なるため、実行する際には本番相当のスペックに変更してから実施するような運用となっています。
また、テストシナリオに必要となる、ユーザーや商品データなども事前に用意する必要があり、負荷テストを実施するには準備作業が発生します。
今後の展望としてこれらの課題を解決し、デプロイパイプラインに組み込んだり、定期的に実行するなど、より簡単、確実に実行できるようにしていきたいと考えています。

大規模なサービス、高トラフィック環境での信頼性の高いサービス構築やその基礎となるプラットフォーム構築に興味がある方など、アソビューでは一緒に働くメンバーを大募集しています! カジュアル面談もありますので、少しでも興味があればお気軽にご応募いただければと思います!

www.asoview.com