あなたはエンドポイントをリリースしました。Postmanでは正しいJSONが返ります。しかし、200クライアントが同時にアクセスしたとき、毎秒500リクエストを処理できるのか、50リクエストでレイテンシが崩れるのかは分かりません。ApacheBenchなら、1コマンドで単一エンドポイントのスループットとレイテンシを確認できます。
ab として呼び出されるApacheBenchは、指定したURLに固定数のHTTPリクエストを送り、スループットとレイテンシを出力するCLIツールです。Apache HTTP Serverに同梱されており、単一エンドポイントの負荷耐性を素早く確認する用途に向いています。
この記事では、ab のインストール、基本的なGETテスト、POSTエンドポイントのテスト、出力の読み方、そして ab を使うべきでないケースを実装手順ベースで説明します。ここで使うフラグは、公式の Apache abリファレンス に対応しています。
ApacheBenchとは何か
ab は、Apache HTTP Serverにバンドルされているベンチマーククライアントです。単一URLに対して接続を開き、指定した同時実行数でリクエストを送り、各レスポンス時間を計測します。
ab が測定できるのは、主に次の2つです。
- 単一エンドポイントが処理できる毎秒リクエスト数
- 負荷がかかったときのレスポンス時間の分布
つまり、1つのURLに対するスループットとレイテンシを見るためのツールです。
一方で、ab はレスポンスボディの正しさを検証しません。JSONスキーマの検証、フィールド値のアサーション、ログインから更新までの多段階フローの実行もできません。1つのURLにリクエストを送り、結果を数えるだけです。
ab がAPI負荷テスト全体の中でどこに位置づけられるかを整理したい場合は、API負荷テストとは何か と APIレスポンス時間がなぜ重要か も参考になります。
abのインストール
ab はApache関連ユーティリティとして配布されています。パッケージ名はOSによって異なります。
Debian / Ubuntu
sudo apt-get update
sudo apt-get install -y apache2-utils
CentOS / RHEL / Fedora
# CentOS 7
sudo yum install -y httpd-tools
# Fedora and CentOS 8+
sudo dnf install -y httpd-tools
macOS
macOSでは、多くの場合 ab がすでに利用できます。
ab -V
Version 2.3 のようなバージョン情報が表示されれば準備完了です。
コマンドが見つからない場合は、Homebrew経由でApacheをインストールし、再度確認してください。
brew install httpd
ab -V
基本的な負荷テストを実行する
ab で最初に覚えるフラグは -n と -c です。
-
-n requests: 実行するリクエスト総数 -
-c concurrency: 同時に実行するリクエスト数
例えば、JSONエンドポイントに対して1000リクエストを50並列で送る場合は次のように実行します。
ab -n 1000 -c 50 https://api.example.com/v1/users
ab にはパスを含む完全なURLが必要です。ルートをテストする場合も、末尾の / を含めます。
ab -n 1000 -c 50 https://api.example.com/
KeepAliveを有効にする
実際のブラウザやAPIクライアントは、通常リクエストごとにTCP接続を作り直しません。接続再利用に近い条件で測るには -k を追加します。
ab -n 1000 -c 50 -k https://api.example.com/v1/users
-k を付けた結果と付けない結果を比較すると、接続確立コストがレイテンシにどれくらい影響しているかを確認できます。
時間ベースで実行する
リクエスト数ではなく、実行時間で制限したい場合は -t を使います。
ab -t 30 -c 50 -k https://api.example.com/v1/users
この例では、同時実行数50で最大30秒間テストします。固定時間で負荷をかけたいときに便利です。
POSTエンドポイントをテストする
POST APIをテストする場合は、リクエストボディをファイルに保存し、-p で指定します。JSON APIでは -T application/json も必ず指定します。
まず、ペイロードを作成します。
cat > payload.json <<'EOF'
{"name": "Ada Lovelace", "email": "ada@example.com"}
EOF
次に、POSTリクエストを実行します。
ab -n 500 -c 25 -k \
-p payload.json \
-T application/json \
https://api.example.com/v1/users
各フラグの意味は次の通りです。
-
-p payload.json: POSTボディとして使うファイル -
-T application/json:Content-Typeヘッダー -
-n 500: 合計500リクエスト -
-c 25: 25並列 -
-k: KeepAlive有効
認証が必要なAPIでは、-H でヘッダーを追加します。
ab -n 500 -c 25 -k \
-p payload.json \
-T application/json \
-H "Authorization: Bearer YOUR_TOKEN" \
https://api.example.com/v1/users
複数のヘッダーが必要な場合は、-H を繰り返します。
ab -n 500 -c 25 -k \
-p payload.json \
-T application/json \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Request-Source: ab-test" \
https://api.example.com/v1/users
JSONリクエストボディの作り方を確認したい場合は、curlでJSONデータをPOSTする方法 を参照してください。同じJSONを ab のペイロードファイルとして利用できます。
出力の読み方
ab を実行すると、次のような結果が出力されます。
Concurrency Level: 50
Time taken for tests: 4.212 seconds
Complete requests: 1000
Failed requests: 0
Non-2xx responses: 0
Requests per second: 237.42 [#/sec] (mean)
Time per request: 210.598 [ms] (mean)
Time per request: 4.212 [ms] (mean, across all concurrent requests)
Transfer rate: 142.31 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 5 18 9.4 16 64
Processing: 22 189 41.2 182 310
Waiting: 21 177 39.8 171 295
Total: 31 207 42.7 201 338
Percentage of the requests served within a certain time (ms)
50% 201
66% 221
75% 236
90% 268
95% 291
99% 324
100% 338 (longest request)
まず確認すべき項目は次の4つです。
Requests per second
Requests per second: 237.42 [#/sec] (mean)
スループットの主要指標です。数値が高いほど、同じ時間で多くのリクエストを処理できています。
ただし、この数値だけで判断してはいけません。エラーが大量に出ている状態でも、表面上のRPSは高く見えることがあります。
Failed requests / Non-2xx responses
Failed requests: 0
Non-2xx responses: 0
負荷をかけた結果、サーバーが正常に応答できたかを確認します。
特に次のような状態では、RPSが高くても有効な結果とは言えません。
-
Failed requestsが多い -
Non-2xx responsesが増えている - 500系エラーが発生している
- タイムアウトが増えている
Time per request
Time per request: 210.598 [ms] (mean)
Time per request: 4.212 [ms] (mean, across all concurrent requests)
Time per request は2行あります。
1行目は、ユーザー視点の平均待ち時間に近い値です。
2行目は、全同時実行リクエストをまたいだ平均処理間隔です。
API利用者が体感するレイテンシを見るなら、主に1行目を見ます。
パーセンタイル
Percentage of the requests served within a certain time (ms)
50% 201
95% 291
99% 324
この表が実運用では重要です。
-
50%: 中央値 -
95%: 95パーセンタイル -
99%: 99パーセンタイル
平均値だけでは、遅いリクエストの影響が見えにくくなります。実際のユーザー体験を考えるなら、95パーセンタイルと99パーセンタイルを必ず確認してください。
この例では、半分のリクエストは201ms以内に完了していますが、1%は324ms以上かかっています。
結果をCSVやTSVで保存する
チャート化したい場合は、-e または -g を使います。
CSVで保存する
ab -n 1000 -c 50 -k \
-e results.csv \
https://api.example.com/v1/users
-e results.csv は、パーセンタイルと時間のペアをCSVとして出力します。
gnuplot向けTSVで保存する
ab -n 1000 -c 50 -k \
-g results.tsv \
https://api.example.com/v1/users
-g results.tsv は、gnuplotで扱いやすい形式のファイルを生成します。
実践的なテスト手順
単発で大きな負荷をかけるより、段階的に同時実行数を上げる方が原因を追いやすくなります。
例えば、次のように実行します。
ab -n 1000 -c 10 -k https://api.example.com/v1/users
ab -n 1000 -c 25 -k https://api.example.com/v1/users
ab -n 1000 -c 50 -k https://api.example.com/v1/users
ab -n 1000 -c 100 -k https://api.example.com/v1/users
各実行で見るべきポイントは次の通りです。
- RPSがどこまで伸びるか
- どの同時実行数でRPSの伸びが止まるか
- 95p / 99pレイテンシが急に悪化する点はどこか
-
Failed requestsやNon-2xx responsesが増え始める点はどこか
RPSが頭打ちになり、テールレイテンシやエラーが増え始める地点が、そのエンドポイントの飽和点の目安です。
abが適切なツールでなくなる場合
ab は便利ですが、用途は狭いです。次のケースでは別のツールを検討してください。
1実行につき1つのURLしか扱えない
ab は単一エンドポイントだけをテストします。
例えば、次のようなフローは扱えません。
- ログインする
- トークンを取得する
- リソースを作成する
- 作成したリソースを取得する
- 更新する
実ユーザーの操作は複数エンドポイントを順番に呼び出すことが多いため、そのようなシナリオには向いていません。
レスポンスの正しさを検証しない
ab はステータスコードやレスポンスサイズを数えますが、JSONの中身は検証しません。
例えば、次のような問題は検出できません。
- 必須フィールドが欠けている
- 型が間違っている
- スキーマに違反している
- 値が期待と異なる
負荷テストの前に、通常条件でAPIが正しいレスポンスを返すことを別途確認する必要があります。
HTTP/2をサポートしない
公式ドキュメントによると、ab はHTTP/1.xも完全には実装していません。HTTP/2はサポートしていません。
HTTP/2での挙動が重要なAPIでは、HTTP/2対応の負荷テストツールを使う必要があります。
単一マシンからの負荷に限られる
ab は1つのマシン、1つのプロセスから負荷をかけます。
同時実行数を大きくしすぎると、サーバーではなく、ab を実行しているクライアント側がボトルネックになることがあります。
多段階シナリオや分散負荷が必要な場合は、JMeter のようなツールを検討できます。選択肢を比較したい場合は、負荷テストツールのまとめ も参考になります。
機能テストと組み合わせる
スループットは重要ですが、それだけではAPI品質を判断できません。APIは速いだけでなく、正しいレスポンスを返す必要があります。
ab は負荷を測るツールです。正確性の検証は、機能テストや契約テストで行います。
Apidog を使うと、次のようなAPIテストシナリオを作成できます。
- 視覚的なアサーションを使った検証
- 複数リクエストをつなげたシナリオ
- レスポンスのスキーマ検証
- 保存したシナリオの再利用
これらは ab が設計上扱わない領域です。
Apidog CLIでCIに組み込む
CIで保存済みシナリオを実行する場合は、Apidog CLIを使えます。
まず、Node環境にCLIをインストールします。
npm install -g apidog-cli
次に、保存済みのシナリオまたはスイートを指定して実行します。
apidog run \
--access-token "$APIDOG_ACCESS_TOKEN" \
-t <TARGET_ID> \
-e <ENV_ID> \
-r cli,html,junit
主なフラグは次の通りです。
-
-t: 保存済みシナリオ、フォルダー、またはスイートのID -
-e: 実行環境のID -
-r: レポーター。cli、html、json、junitなどを指定可能 -
-d/--iteration-data: データ駆動テスト用のデータファイルパスまたはテストデータID
例えば、CIでJUnitレポートを保存したい場合は、次のような流れになります。
npm install -g apidog-cli
apidog run \
--access-token "$APIDOG_ACCESS_TOKEN" \
-t <TARGET_ID> \
-e <ENV_ID> \
-r cli,junit
健全な構成では、次のように役割を分けます。
- Apidogで機能テストを実行し、APIが正しいことを確認する
-
abで単一エンドポイントのスループットとレイテンシを測定する
正確性とパフォーマンスの両面を扱いたい場合は、Apidogのパフォーマンステストガイド と APIパフォーマンステストチュートリアル も参照してください。
よくある質問
ApacheBenchはApacheサーバー専用ですか?
いいえ。ab は通常のHTTP/HTTPSリクエストを送るクライアントです。Nginx、Node.js、Go、Pythonなど、HTTPを話すサーバーであればテストできます。
Apacheとの関係は、ab がApache HTTP Serverに同梱されているという点だけです。
どの同時実行数とリクエスト数を使うべきですか?
低い値から始めて段階的に上げます。
例:
ab -n 1000 -c 10 -k https://api.example.com/v1/users
ab -n 1000 -c 25 -k https://api.example.com/v1/users
ab -n 1000 -c 50 -k https://api.example.com/v1/users
ab -n 1000 -c 100 -k https://api.example.com/v1/users
RPSが伸びなくなり、95p / 99pレイテンシやエラーが増える点を確認してください。その地点が、おおよその飽和点です。
APIは正常なのにFailed requestsが多いのはなぜですか?
ab はレスポンス長がリクエスト間で異なると、失敗として扱うことがあります。動的なJSONレスポンスでは、レスポンスサイズが変わるのは自然です。
その場合は -l を追加します。
ab -n 1000 -c 50 -k -l https://api.example.com/v1/users
そのうえで、Non-2xx responses を確認し、実際のHTTPエラーが発生していないかを見てください。
abはログインが必要なエンドポイントをテストできますか?
トークンをすでに持っている場合は可能です。
ab -n 500 -c 25 -k \
-H "Authorization: Bearer YOUR_TOKEN" \
https://api.example.com/v1/me
ただし、ab はログインしてトークンを取得し、そのトークンを次のリクエストで使うような多段階フローは実行できません。その場合は、Apidogのようなシナリオベースのツールが必要です。
abはHTTP/2をサポートしていますか?
いいえ。ab はHTTP/1.x向けのツールで、HTTP/2はサポートしていません。
HTTP/2での性能や挙動を測定したい場合は、HTTP/2対応の負荷テストツールを使ってください。

Top comments (0)