APIはすべての機能テストに合格しても、本番環境で失敗することがあります。正しいデータ、正しいステータスコード、正しいスキーマで応答しても、同時に何千ものユーザーがアクセスした瞬間に機能しなくなります。機能テストはAPIが正しいことを示します。パフォーマンステストは、APIが正しいだけでなく、実際のトラフィックに耐えられるほど高速であることを示します。
このガイドでは、APIパフォーマンステストとは何か、重要なテストタイプ、注目すべきメトリクス、そしてApidogでパフォーマンステストを段階的に実行する方法について説明します。
APIパフォーマンステストとは
APIパフォーマンステストは、APIが負荷の下でどのように動作するかを測定します。具体的には、応答速度、処理できるリクエスト数、そしてどの時点で性能が低下したり、破損したりするかを評価します。応答が正しいかどうかを問うものではありません。それは機能テストです。システムが負荷を受けているときに、応答が迅速かつ確実に届くかどうかを問うものです。
目標は、ユーザーが限界に気づく前にそれを見つけることです。すべてのAPIには上限があり、応答時間が上昇したり、エラーが発生したり、サービスが応答を停止したりする点があります。パフォーマンステストは、その上限を制御された環境で特定し、それに応じて上限を引き上げたり、キャパシティを計画したり、少なくともそこに上限があることを認識したりできるようにします。
APIは決定論的で呼び出しが高速であるため、パフォーマンステストの優れたターゲットです。レンダリングするブラウザや、待機するUIはありません。リクエストを送信し、応答を測定するだけです。これにより、APIパフォーマンステストは、完全なエンドツーエンドのロードテストよりも実行コストが低く、安定しています。
パフォーマンステストの種類
「パフォーマンステスト」は包括的な用語です。その下には、それぞれ異なる問いに答えるいくつかの明確なテストタイプがあります。
ロードテストは、実際に予想されるトラフィック、つまり通常のピーク時のリクエスト量を適用し、APIが許容できる応答時間内でそれらを処理することを確認します。これはほとんどのチームが最初に実行するベースラインテストです。
ストレステストは、予想されるトラフィックを超えて負荷を増やし、APIが性能低下または障害を起こすまで実行します。目的は、限界点を見つけ、どのように壊れるかを確認することです。優雅に遅くなるのか、それともエラーを返してデータを失うのか。
スパイクテストは、フラッシュセールやバイラルな瞬間が生み出すような、突然の急激なトラフィックの増加を適用し、APIがそれを吸収できるか、それともクラッシュするかを確認します。安定した負荷を処理できるシステムでも、スパイクで失敗することがあります。
ソークテスト(耐久性テストとも呼ばれる)は、数時間または数日間、中程度の負荷を長時間維持し、メモリリーク、接続プールの枯渇、ディスクを埋め尽くすログファイルなど、ゆっくりと現れる問題を発見します。これらは5分間のロードテストでは決して現れません。
スモークテストは軽量な事前チェックです。APIとテスト設定が機能していることを確認するための少量の負荷で、長く費用のかかる実行にコミットする前に実施します。
ほとんどのチームは、最低限ロードテスト、ストレステスト、ソークテストを必要とします。トラフィックがバースト的である場合は、スパイクテストが重要になります。
重要なメトリクス
パフォーマンステストは数値を生み出します。これらが読み取るべきものです。
応答時間は、APIがリクエストを受信、処理し、返信するまでにかかる時間です。平均値だけでなく、パーセンタイル値に注目してください。平均値が健全に見えても、95パーセンタイルや99パーセンタイル(最も遅い5%と1%のリクエスト)が許容できない場合があります。実際のユーザーはテールレイテンシを感じます。
スループットは、APIが1秒間に完了するリクエストの数です。これは、接続されているユーザー数に関係なく、システムの実際のキャパシティを示します。
同時実行ユーザー数または仮想ユーザー数は、テストがシミュレートする同時呼び出し元の数です。キャパシティは、応答時間が予算を超える前にAPIが維持できる最大同時実行数として表現されることがよくあります。
エラー率は、負荷の下で失敗したリクエストの割合です。高速を維持しながらも、高い同時実行数で500エラーを返し始めるAPIは、テストに失敗したことになります。
リソース使用率(サーバーのCPUとメモリ)は、パフォーマンスが低下する理由を示します。CPUが100%の状態で応答時間が上昇している場合、計算リソースがボトルネックです。CPUがアイドル状態なのにレイテンシが上昇している場合、ボトルネックは別の場所(多くの場合データベースまたはダウンストリームコール)にあります。
優れたパフォーマンスレポートは、これらを結びつけます。つまり、「この同時実行数でスループットはピークに達し、95パーセンタイルの応答時間はこれであり、エラー率はそれであった」という具合です。
ApidogでAPIパフォーマンステストを実行する方法
Apidogには、APIの設計と機能テストを行うのと同じワークスペースにロードテスト機能が組み込まれているため、別途ツールを用意する必要はありません。
ステップ1:テストするエンドポイントまたはシナリオを選択する。 重要な単一のエンドポイント、またはログイン後のデータ取得など、実際のユーザーフローを模倣する複数ステップのテストシナリオを選択します。単一のエンドポイントを個別に叩くよりも、現実的なフローをテストする方がより正確な数値が得られます。
ステップ2:まず機能的にパスすることを確認する。 リクエストをそのアサーションと共に一度実行します。誤ったデータを返すエンドポイントをロードテストしても意味がありません。速度を測定する前に、まず正確性を修正してください。
ステップ3:負荷を構成する。 仮想ユーザー数とテスト期間を設定します。Apidogでは、すべてのユーザーが一度に加わるのではなく、時間の経過とともにユーザーが徐々に参加するのをシミュレートする段階的な増加が可能です。これにより、より現実的な状況が再現され、パフォーマンスが変化する同時実行レベルを特定するのに役立ちます。
ステップ4:テストを実行する。 Apidogは負荷を実行し、リアルタイムでレポートします。応答時間、スループット、エラー率、そして同時実行数が増加するにつれて各メトリクスがどのように変化するかを確認できます。応答時間が負荷よりも速く上昇し始める変曲点に注目してください。
ステップ5:結果を読み、ボトルネックを見つける。 300人の同時実行ユーザーで95パーセンタイル応答時間が予算を超えた場合、それが現在の限界です。サーバーのCPUとメモリを参照して原因を理解してください。修正後に再実行して、限界が移動したことを確認します。
ステップ6:より高度なニーズにはJMeterにエクスポートする。 単一のマシンを超える分散負荷生成が必要な場合、ApidogはシナリオをJMeterにエクスポートできます。これにより、負荷ソースをスケールしながらも同じテスト定義を維持できます。
既存のエンドポイントに対して最初のロードテストを実行するには、Apidogをダウンロードしてください。
実際のパフォーマンス結果の読み方
解釈のない数値はノイズです。具体的な実行例を見てみましょう。仮想ユーザーを5分間で0から500に増やしながら、GET /productsのロードテストを実行します。
最初の200ユーザーについては、95パーセンタイルの応答時間は約180ミリ秒で安定し、スループットは負荷に比例して上昇します。これは健全なゾーンであり、APIは対応できています。約280ユーザーで、95パーセンタイルの応答時間が上昇し始め、240ミリ秒、次に400ミリ秒、そして900ミリ秒となり、スループットは上昇する代わりに横ばいになります。この横ばいはAPIが限界に達したことを示しています。これ以上ユーザーを追加しても、処理される作業が増えるのではなく、応答が遅くなるだけです。420ユーザーを超えると、リクエストがタイムアウトし始め、エラー率が1%を超えるようになります。
結論は明確です。このAPIは、200ミリ秒の予算内で約250人の同時実行ユーザーに快適にサービスを提供します。その実用的な限界は約280であり、約420で障害が発生し始めます。ピーク時のトラフィックが200同時実行ユーザーを予想している場合、余裕があります。もし350を予想している場合、リリース後ではなく、リリース前に修正すべき問題があります。
これがパフォーマンステストが提供するものです。「合格」または「不合格」ではなく、APIが快適に動作する場所、負荷がかかる場所、そして壊れる場所を明確に示すマップです。
一般的なAPIパフォーマンスのボトルネック
テストが限界を明らかにする場合、その原因は通常、いくつかのおなじみの犯人のいずれかです。
遅いデータベースクエリが最も一般的です。インデックスが張られていないカラム、N+1クエリパターン、またはクエリ制限の欠如は、データ量や同時実行数が増加した瞬間に高速なエンドポイントを遅くします。サーバーCPUが低いままレイテンシが上昇する場合、まずデータベースを疑ってください。
ブロッキング外部呼び出しは、エンドポイントを最も遅い依存関係の速度まで引きずり下ろします。決済プロバイダーやサードパーティサービスを同期的に呼び出すAPIは、そのサービスのレイテンシとその停止を継承します。
接続プールの枯渇は、持続的な負荷の下で現れます。APIがデータベース接続またはHTTPクライアントを使い果たし、リクエストが待機状態になります。これは典型的なソークテストでの発見です。
大きな応答ペイロードの非効率なシリアル化はCPUを消費します。クライアントが必要とする以上のデータを返すことは、すべての応答の構築と転送を遅くします。
パフォーマンステストは、上限がどこにあるかを示し、それをサーバー側のメトリクスと組み合わせることで、なぜそうなるのかがわかります。
プロセスにパフォーマンステストを組み込む
大規模なリリース前に一度実行されるパフォーマンステストは役立ちます。しかし、定期的に実行されるパフォーマンステストははるかに価値があります。なぜなら、パフォーマンスは静かに劣化するからです。新しいデータベースクエリ、追加されたダウンストリームコール、またはインデックスが張られていないカラムは、機能テストでは気づかないレイテンシを追加する可能性があります。
重要なエンドポイントに対して応答時間とエラー率の予算を設定し、その違反を、アサーションの破損と同じように失敗として扱います。CI/CDの一部として軽量なロードテストを実行し、プルリクエストの段階でパフォーマンスの退行が明らかになるようにします。また、大規模なストレステストやソークテストは、予定されたリリース前テストのために確保しておきましょう。
パフォーマンステストを機能テストの隣に置きます。これら2つが共存することで、APIの変更ごとに正確性と速度の両方がチェックされ、「動作するか」と「十分速く動作するか」という別々の、忘れ去られがちな問題ではなくなります。
よくある質問
ロードテストとストレステストの違いは何ですか? ロードテストは、予想されるトラフィックを適用し、APIがそれを処理することを確認します。ストレステストはそれを超えて負荷をかけ、限界点を見つけます。ロードテストは通常の動作を検証し、ストレステストは障害モードをマッピングします。
平均応答時間とパーセンタイル応答時間のどちらを見るべきですか? パーセンタイルです。平均値は遅いテールを隠します。95パーセンタイルと99パーセンタイルは、最も運の悪いユーザーが実際に経験するものを表しており、それが苦情の原因となります。
バックエンドが完成する前にAPIのパフォーマンステストを行うことはできますか? 契約と設計はテストできますが、意味のあるレイテンシの数値を得るには実際のインフラが必要です。初期の機能開発にはモックサーバーを使用し、実際の実装に対してロードテストを実行してください。
パフォーマンステストはどのくらいの頻度で実行すべきですか? 重要なエンドポイントに対する変更があるたびにCIで軽量なロードテストを実行し、主要なリリース前には毎回フルストレステストとソークテストを実行してください。パフォーマンスは静かに劣化するため、リリース前の大規模な一度のテストよりも定期的なチェックが優れています。
