HTTPエンドポイントを作成しました。Postmanから一度叩けば動作します。しかし、200のクライアントが同時に叩いた場合はどうなるでしょうか?必要なのは、1秒あたりのリクエスト数、レイテンシのパーセンタイル値、そして2xx以外のステータスで返されたレスポンスの数です。autocannonは、これらの数値を約10秒でターミナルに表示します。
autocannonは、Node.jsで書かれたHTTP/1.1ベンチマーキングツールです。指定したURLに対して制御された大量のリクエストを送信し、スループットとレイテンシをレポートします。このガイドでは、インストール方法、基本的な実行方法、実際に使用するすべてのフラグ、出力の読み方、およびNodeスクリプトからautocannonを操作する方法について説明します。また、ロードテストでわかることとわからないことの明確な線引きも示しており、機能テストや契約テストを代わりに使うべき時を知ることができます。
autocannonとは
autocannonは、指定されたURLに対して一定数の同時接続を開き、設定された期間(または設定されたリクエスト数)にわたってリクエストを送り続けます。実行中は、レイテンシをサンプリングし、レスポンス数をカウントします。終了すると、レイテンシのパーセンタイル値の表と、合計リクエスト数および読み取ったバイト数の概要が表示されます。

これは、サーバーがどれくらいの負荷を処理できるか、そしてその負荷の下でどれくらいの速さで応答するかという一点を測定します。レスポンスボディが正しいか、APIがOpenAPI仕様と一致しているか、あるいは複数ステップのワークフローが各ステップで正しいデータを返すかといったことはチェックしません。この区別を覚えておいてください。これにより、autocannonがあなたのテストスタックのどこに適合するかが決まり、その詳細は最後に説明します。
wrkやApache Benchを使用したことがあるなら、autocannonはNodeネイティブのインストールとJavaScriptから呼び出せるプログラマティックAPIによって、同じ役割を担います。
インストール
autocannonはnpmパッケージとして提供されています。どこからでもautocannonコマンドを使えるように、グローバルにインストールします。
npm i autocannon -g
まずNode.jsがインストールされている必要があります。グローバルにインストールしたくない場合は、npxを使ってオンデマンドで実行します。
npx autocannon http://localhost:3000
または、スクリプト化する予定がある場合は、開発依存関係としてプロジェクトに追加します。
npm i autocannon --save-dev
インストールを確認します。
autocannon --version
基本的な実行
最もシンプルな形式は、コマンドとURLを組み合わせるものです。これにより、デフォルトのベンチマーク(10秒間、10接続)が実行されます。
autocannon http://localhost:3000
常に使用する3つのフラグで調整します。-cは同時接続数を設定し、-dは持続時間(秒単位)を設定し、-pはパイプライン処理(各接続が応答を待つ前に送信するリクエスト数)を設定します。
autocannon -c 100 -d 30 -p 10 http://localhost:3000
このコマンドは、100の接続を開き、30秒間実行し、各接続につき10個のリクエストをパイプライン処理します。接続数とパイプライン処理数を増やすことでより多くの負荷がかかり、これによってレイテンシが上昇し始めるポイントを見つけることができます。
一定期間実行する代わりに、固定数のリクエストを送信するには、-a(amount)を使用します。
autocannon -c 10 -a 10000 http://localhost:3000
これは時間に関係なく10,000リクエストの後に停止します。
POSTリクエスト、ヘッダー、およびボディ
-mでメソッドを変更し、-Hでヘッダーを追加し、-bでリクエストボディを渡します。以下はJSONエンドポイントへのPOSTの例です。
autocannon -c 50 -d 20 \
-m POST \
-H 'Content-Type=application/json' \
-H 'Authorization=Bearer YOUR_TOKEN' \
-b '{"name":"load-test","active":true}' \
http://localhost:3000/api/users
ヘッダーの形式は-H 'Key=Value'であることに注意し、各ヘッダーに対して-Hを繰り返します。ボディが大きい場合やファイルに保存されている場合は、インラインで記述する代わりに-iを使用してディスクから読み込みます。
autocannon -m POST -H 'Content-Type=application/json' -i payload.json http://localhost:3000/api/users
テストのレート制限
デフォルトでは、autocannonは可能な限り高速でリクエストを送信します。しかし、最大負荷をかけるのではなく、安定した現実的なレートでテストしたい場合があります。-Rは、すべての接続における1秒あたりの合計リクエスト数を制限します。
autocannon -c 50 -R 500 -d 60 http://localhost:3000
これにより、テストは60秒間、毎秒500リクエストに維持されます。これは、限界点ではなく、予想される本番環境の負荷でのレイテンシを測定したい場合に役立ちます。
ウォームアップとワーカー スレッド
さらに2つのフラグが、より重い実行に役立ちます。-W(ウォームアップ)は、autocannonがサンプリングを開始する前に短時間トラフィックを送信し、コールドキャッシュやウォームアップされていないJITによって最初の数値が歪められないようにします。-w(ワーカー)は、負荷を複数のNodeワーカー スレッドに分散させます。これは、単一のスレッドでは高速サーバーを飽和させるのに十分なリクエストを生成できない場合に重要です。
autocannon -c 200 -d 30 -w 4 http://localhost:3000
-wは、負荷ジェネレーター自体がボトルネックであることを確認した場合にのみ使用してください。-cを増やしてもレイテンシが不審なほどフラットに見える場合、ジェネレーターが最大に達している可能性があり、ワーカーを追加することでサーバーの限界をより正確に把握できます。
結果の読み方
実行が完了すると、autocannonはレイテンシの表と概要行を表示します。以下に省略された例を示します。
http://localhost:3000 で10秒テストを実行中
10接続
┌─────────┬──────┬──────┬───────┬──────┬─────────┬─────────┬──────────┐
│ 統計 │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
├─────────┼──────┼──────┼───────┼──────┼─────────┼─────────┼──────────┤
│ レイテンシ│ 0 ms │ 1 ms │ 4 ms │ 6 ms │ 1.2 ms │ 0.9 ms │ 24.1 ms │
└─────────┴──────┴──────┴───────┴──────┴─────────┴─────────┴──────────┘
10.05秒で25.1万リクエスト、27.9 MB読み込み済み
読み方は以下の通りです。
- パーセンタイル列(2.5%、50%、97.5%、99%)は平均値よりも重要です。50%列は中央値です。99%列は、最も遅い1%のユーザーが経験するレイテンシを示します。テールレイテンシは実際の問題が隠れている場所なので、97.5%と99%の数値に注目してください。
- AvgとStdevは、平均値とレイテンシのばらつきを示します。高い標準偏差は、応答時間が不安定であることを意味します。
- 概要行(「10.05秒で25.1万リクエスト」)はスループットです。リクエスト数を秒数で割ると、1秒あたりのリクエスト数になります。
2つのフラグで出力をより有用にできます。-lを追加すると、完全なレイテンシパーセンタイルセット(p99.9以降を含む)が表示され、--renderStatusCodesを追加すると、ステータスコードごとの内訳が表示されるため、良好なスループット数値の裏に隠れている大量の500エラーを検出できます。
autocannon -c 100 -d 20 -l --renderStatusCodes http://localhost:3000
エラー、タイムアウト、および2xx以外のカウントに注意してください。サーバーは高いリクエストレートを示しながらも、ひっそりとエラーを返している場合があります。2xx以外の数値がゼロでない場合、スループットの数値は成功ではなく失敗を測定していることになります。
スクリプトでのプログラマティックな使用
autocannonはNode.js APIを公開しているため、スクリプトからベンチマークを実行し、その結果に基づいてアクションを実行できます。自動化でその真価を発揮するのはここです。テストを実行し、数値を読み取り、レイテンシが閾値を超えた場合にビルドを失敗させます。
const autocannon = require('autocannon')
async function run() {
const result = await autocannon({
url: 'http://localhost:3000',
connections: 100,
duration: 20,
pipelining: 1
})
console.log(`Avg latency: ${result.latency.average} ms`)
console.log(`Req/sec: ${result.requests.average}`)
console.log(`Non-2xx: ${result.non2xx}`)
}
run()
resultオブジェクトには、latency、requests、およびthroughputのヒストグラムが含まれており、それぞれにaverage、min、max、およびp99のようなパーセンタイルフィールドがあります。また、errors、timeouts、およびnon2xxのカウントも含まれています。
それをゲートにするには、予算超過時にゼロ以外の値で終了するチェックを追加します。
const autocannon = require('autocannon')
const P99_BUDGET_MS = 250
async function run() {
const result = await autocannon({
url: 'http://localhost:3000/api/health',
connections: 100,
duration: 30
})
const p99 = result.latency.p99
console.log(`p99 latency: ${p99} ms (budget ${P99_BUDGET_MS} ms)`)
if (p99 > P99_BUDGET_MS || result.non2xx > 0) {
console.error('Performance budget exceeded')
process.exit(1)
}
}
run()
CLIが表示するライブのプログレスバーと結果テーブルが必要な場合は、インスタンスをautocannon.trackに渡します。
const autocannon = require('autocannon')
const instance = autocannon({
url: 'http://localhost:3000',
connections: 10,
duration: 10
}, console.log)
autocannon.track(instance, { renderProgressBar: true })
process.once('SIGINT', () => instance.stop())
複数リクエストのシナリオでは、各接続が複数の呼び出しを繰り返すようにrequests配列を渡します。
autocannon({
url: 'http://localhost:3000',
connections: 20,
duration: 15,
requests: [
{ method: 'GET', path: '/api/users' },
{ method: 'POST', path: '/api/data', body: '{"x":1}',
headers: { 'Content-Type': 'application/json' } }
]
}, console.log)
autocannon vs wrk および ab
これら3つはすべて同じ質問(どれくらいの速さで、どれくらいの負荷の下で)に答えるものであり、適切な選択はあなたのスタックに依存します。
- Apache Bench (ab)は、古典的な単一バイナリツールです。どこでも利用できシンプルですが、シングルスレッドで古くなっています。
- wrkは高速で、カスタムリクエスト用のLuaスクリプトを使用して高い負荷を生成できます。これはコンパイルされたCツールなので、npmとは別にインストールします。
- autocannonは、ほとんどのワークロードでスループットに関してwrkに匹敵し、Node環境ですでに作業している場合は、人間工学的に優れています。
npm iでインストールし、スクリプト用のJavaScript APIがあり、パイプライン処理、HARファイル、およびリクエストごとのシナリオをすぐにサポートします。
Nodeがあなたのランタイムである場合、autocannonは摩擦の少ない選択肢です。Pythonツールを好みますか?Pythonなしでロードテストを行う方法を参照してください。豊富な機能を備えたスクリプト可能なオプションが必要ですか?k6のロードテストを比較してください。
機能テストとApidogが適合する場所
autocannonは、あなたのエンドポイントがp99で40msのレイテンシで毎秒12,000リクエストを処理することを示します。しかし、エンドポイントが正しいデータを返すかどうかは教えてくれません。APIが不正なJSONを返したり、認証ヘッダーを無視したり、OpenAPI契約から逸脱したりしている間でも、ロードテストは難なくパスしてしまう可能性があります。スループットは正確性ではありません。
それが機能テストと契約テストが埋めるギャップであり、Apidogがロードツールを補完する場所であり、代替するものではありません。Apidogはロードジェネレーターではありません。ステータスコード、レスポンススキーマ、複数ステップのフロー全体の値についてアサーションを行う保存されたテストシナリオを実行するため、ベンチマークでは見つけられないバグを検出できます。
CIでは両方を実行し、それぞれ異なる質問に答えます。autocannon(またはwrk)は「負荷の下で十分速いか?」という質問に答えるために使用します。Apidog CLIは「正しいか?」という質問に答えるために使用します。Apidog CLIはヘッドレスであり、Nodeが利用可能なCIステップから保存されたテストシナリオまたはスイートを実行します。
npm install -g apidog-cli
apidog run \
--access-token "$APIDOG_ACCESS_TOKEN" \
-t <scenarioOrSuiteId> \
-e <environmentId> \
-r cli,html,junit
-tフラグは、保存されたシナリオ、フォルダー、またはスイートをIDで指定し、-eは環境を選択し、-rは1つ以上のレポーター(cli、html、json、junit)を選択するため、実行結果としてパイプラインでアーカイブできるアーティファクトが生成されます。詳細な手順については、Apidog CLIからAPIテストを実行する方法、コピー&ペーストで使えるCI/CDパイプライン、およびGitHub Actionsワークフローを参照してください。
健全なパイプラインは、プッシュごとに機能チェックと契約チェック(動作するか?)を実行し、リリース前にロードテスト(持ちこたえるか?)を実行します。autocannonは後者の質問を担当し、Apidogは前者の質問を担当します。
よくある質問 (FAQ)
autocannonは本番環境のロードテストで正確ですか?
autocannonはHTTP/1.1エンドポイントに対して信頼性の高いスループットとレイテンシの数値を提供し、-Rで目標レートを設定すると、多くのシンプルなツールが省略する協調省略の補正を行います。正確な結果を得るには、サーバーに近いマシンから実行し(そうしないとネットワークレイテンシが支配的になります)、エンドポイントを飽和させるのに十分な接続数を使用してください。本番環境をミラーリングしたステージング環境に対して実行し、ラップトップの開発サーバーに対して実行しないでください。
autocannonはHTTP/2またはWebSocketをサポートしていますか?
いいえ。autocannonはHTTP/1.1のベンチマークを行います。HTTP/2またはWebSocketのロードテストには別のツールが必要です。これは選択する前に確認すべき主な制約です。
いくつの接続を使用すべきですか?
デフォルトの10から開始し、1秒あたりのリクエスト数が上昇を停止し、レイテンシが上昇し始めるまで-cを増やします。その変曲点がほぼサーバーの容量です。それをはるかに超えて負荷をかけると、サーバーの限界よりも負荷ジェネレーターの限界を測定することになります。
CIでautocannonを実行できますか?
はい、できます。プログラマティックAPIはそのために構築されています。ベンチマークを実行し、result.latency.p99とresult.non2xxを読み取り、予算を超過した場合はprocess.exit(1)を呼び出します。これにより、ベンチマークをNode対応の任意のCIステップに組み込むことができる合否判定ゲートに変換できます。
-aと-dの違いは何ですか?
-dは指定された秒数実行します。-aは指定された数のリクエストが完了するまで実行し、その後停止します。定常状態のロードテストには-dを、正確なリクエスト数を送信したい場合には-aを使用します。
