こんにちは。インフラエンジニアの永井(shnagai)です。
今回は、現在進めているプロジェクトでの負荷試験で、AWS Distributed Load Testing を使って比較的手軽にAWS内での負荷試験を行うことが出来たのでその内容を紹介しようと思います。
内容はざっくり下記3点です。
- これまで使ってきた負荷試験ツールとその悩み
- AWS Distributed Load Testingとは
- 実際の負荷試験の様子
これまで使ってきた負荷試験ツールの悩み
新規システムを開発し、サービスに導入する際には、負荷試験が必要になるケースも多いと思います。
負荷試験は、開発したシステムが想定リクエストに対して性能面で問題なく稼働出来るかをユーザに提供する前にチェックする目的で行うのが一般的です。
内容としては、レイテンシやステータスコードのエラー数等をレポートし、それらが基準として定めたパフォーマンスを満たしているかチェックします。もし想定外の結果が出た際は、負荷試験で露見したボトルネックを潰し、再度計測して基準値を満たせるまでそれを続けます。
負荷試験を行うツールは代表的なものがいくつかあり、ライトなものだとab - Apache HTTP server benchmarking tool、複雑なテストシナリオやレポーティングを求めると、Apache JMeter™ , Tsung ,Gatling - Professional Load Testing Tool等があります。
コネヒトでもケースに応じてこれらのツールを都度検討しつつ負荷試験を実施してきました。
ここでは各ツールの比較はしませんが、個人的な所感だとabは簡単な単一リクエストの負荷試験用途に便利で、その他のツールはそれぞれ特性はありつつも、一度手に馴染んで環境を作ってしまえば負荷試験ツールとして十分に便利だと思っています。
ただ、負荷試験環境を作るのに毎回そこそこのコストがかかるのが個人的にはもったいないなといつも思っていて、実際に下記のような悩みポイントを毎回抱えていました。
- 負荷試験の環境準備には2つあり、負荷をかけられる側とかける側がある。負荷をかける側の準備は本来の開発とは関係ない部分なので、出来るだけ低コストに抑えたいのですがテストの規模やツールによってはその準備に大きなコストがかかるケースがある。負荷をかける側がボトルネックになり期待したパフォーマンスが出ないケースも十分に想定されるのでおざなりには出来ない。 端的にいうと大きめのリクエストをクライアント側をボトルネックにせずに回す環境作るの大変、、、
- 負荷試験の頻度が年に数回なので、nヶ月後にやろうとした時に環境含めたキャッチアップコストがそこそこ高い
以降ではこれらの負荷試験環境の準備コストにかかる悩みを一定解消してくれた AWSマネージドの負荷試験ツールであるAWS Distributed Load Testingを紹介していきます。
※参考までに、今回のツール選定前にざっくりかかげた負荷試験ツールの要件のキャプチャを貼っておきます。
AWS Distributed Load Testingとは
AWS SAに負荷試験について相談したところ、下記ブログを教えてもらいAWS Distributed Load Testingの存在を知りました。
自分なりの解釈で要約すると、下記の特徴があるサービスかなと思っています。
- CloudFormation一発実行で負荷試験の実行環境を作ってくれるサービス
- 負荷試験環境の構成管理不要
- 作られるサービスにはフロントエンドとバックエンドに分かれる
- フロントエンドは、負荷試験の設定やレポートを補完閲覧するためのWebアプリケーション
- バックエンドは、負荷試験でいうところのクライアント環境(負荷掛け機)
- 単純なエンドポイントへのHTTPリクエストの他、Jmeterのシナリオファイルをインポート出来る
- Jmeterのシナリオファイル=複雑なテストシナリオを実行可能
- クライアントはFargateタスクなので、クライアント側のCPU負荷をウォッチすることでリソース不足であれば簡単に設定画面から追加可能
- クライアント側で計測出来る項目に、
Average response time(s)
Requests Per Second
err数(ステータスコードあり)
Percentileレイテンシ
等があり1テスト毎にレポート- 上のレポートを一覧で見ることも可能(項目は固定だが)
これまで都度苦労してきた負荷試験クライアントの準備が、用意されているCloudFormation一発で作成/削除出来るという手軽さが個人的には一番刺さりました。
また、Jmeterのシナリオを使えるので複雑なテストシナリオの実行が可能かつレポートも今回求めているものを満たしていると判断したので、今回の負荷試験ツールとして正式採用することを決めました。
実際の負荷試験の様子
ここでは具体の設定方法には触れず、どのようなフローで負荷試験を回したかを紹介します。
具体の設定方法は、クラメソさんのやってみたシリーズが詳しいのこちらを参照していただくのがよいかなと思います。
AWSの負荷テストソリューションを試してみた | DevelopersIO
負荷試験のフロー
- ローカルのJmeterでシナリオを作る
- CloudFormationを実行して負荷試験環境を作る(ほぼワンクリック)
- VPC内にリソース作ることも可能なのが嬉しいポイント
jmxファイルをZIPに固めて、Distributed Load Testing上でアップロード
- csv等を使う場合は、一緒にzipに固める
- シナリオで読み込ませるファイルのパスをアップロード時の相対パスにする必要があるので注意
- csv等を使う場合は、一緒にzipに固める
General Settingsにある負荷テストの条件を設定して実行
- Task Count
- このテストで利用するFargateのタスク数(Max: 1000)
- Concurrency
- Ramp Up
- 最大同時接続数までに到達する時間
- この時間を使って同時接続数maxまでユーザを徐々に増やしていく
- 0にすると一気に同時接続数に到達
- 最大同時接続数までに到達する時間
- Hold For
- 最大同時接続数によるアクセスを継続する時間
- Task Count
- 実行後の結果を確認し再度設定を変えて基準値を満たすまで実施
- 負荷がけ機(クライアント)側のリソース状況はECSクラスタ関連のCloudWatchで確認
- 負荷をかけられるサービス側はそれぞれのAPIやデータソース側のメトリクスを確認
- 負荷テストの実行結果のレポートはこんな感じでテスト毎に出力されます 実行結果としてレポートされる項目の一覧は下記です。
- Average response time : テストによって生成されたすべてのリクエストの平均応答時間 (秒)
- Average latency : テストによって生成されたすべてのリクエストの平均レイテンシー (秒)
- Average connection time : テストで生成されたすべてのリクエストについて、ホストへの接続にかかった平均時間 (秒)
- Average bandwidth : テストで生成されたすべてのリクエストの平均帯域幅
- Total Count : リクエストの総数
- Success Count : 成功したリクエストの総数
- Error Count : エラーの総数
- Requests Per Second : テストで生成されたすべてのリクエストの 1 秒あたりの平均リクエスト数
- Percentile : テストの応答時間のパーセンタイル値 (最大応答時間は 100 %、最小応答時間は 0 %)
- 負荷試験の結果、基準値を満たせたらCloudFormationのスタック削除で環境がまるっと削除されるので後片付け終了
負荷試験のまとめとして、実行結果と付随情報を一覧出来るようにまとめて最終的なレポートは自作しました。どの負荷試験ツールを使ってもこれは一緒で、実際のサービス側のリソース状況(CPU,mem等)と負荷試験レポートの相関関係が一望出来ないと意図しない結果の時にボトルネックがわかりにくくなるため一覧出来るようにしています。
ただ、Distributed Load Testingのレポートベースで作れるので作成コストは非常に小さく済みました。
今回は、AWS Distributed Load Testingを使って比較的簡単にAWS内で負荷試験を実施した事例を紹介しました。
個人的には、負荷試験の環境準備にかかるコストが劇的に減った感覚があるので非常におすすめのサービスです。
最後に宣伝です! コネヒトでは一緒に成長中のサービスを支えるために働く仲間を様々な職種で探しています。 少しでも興味もたれた方は、是非気軽にオンラインでカジュアルにお話出来るとうれしいです。