利益:
- 速度制限 (RPM/ITPM/OTPM) と 429 エラーを解釈できます
- 指数バックオフを実装し、retry-after を使用して再試行します。
- 一般的な HTTP エラー コード (400/401/429/500/529) を正しく分類して処理します。
実稼働環境では、常に完璧に応答する API は存在しません。場合によっては、リクエストを送信するのが速すぎて制限に達してしまうことがあります。サーバーが一時的にビジー状態になる場合があります。あなたの要求が最初から間違っている場合もあります。堅実な統合とアマチュアの試みの違いは、これらの状況を予測的かつ自動的に処理することです。この単元では、レート制限 (RPM/ITPM/OTPM)、429 エラー、指数バックオフによる再試行、一般的な HTTP エラー コードの適切な分類について学習します。目標は、ユーザーが気付かないほど堅牢なフローを構築することです。
制限速度とは何ですか?
プロバイダーは、スイッチが一定期間内に実行できる作業量を制限します。この保護。突然のコストの爆発からインフラストラクチャとユーザーの両方を保護します。制限には一般的に 3 つのタイプがあります。
- RPM (Requests Per Minute): 1 分あたりのリクエスト数。
- ITPM (Input Tokens Per Minute): 1 分あたりに処理できる入力トークン。
- OTPM (Output Tokens Per Minute): 1 分あたりに生成できる出力トークン。
これらの制限のいずれかを超えると、プロバイダーはリクエストを拒否し、429 エラー コードを返します。制限は通常、アカウント レベル (層) によって異なり、時間の経過とともに増加する可能性があります。
ヒント: 応答ヘッダーから制限に近づいていることを監視できます。ほとんどのプロバイダーは、x-ratelimit-remaining-* のようなヘッダーで残りのクォータを報告します。これらの値を監視し、前方のトラフィックを抑制することが、429 を取得せずに問題を防ぐ最も成熟した方法です。
429 と指数リトレースメント
429 (レート制限) は一時的な再試行可能なエラーです。正しい応答は、リクエストをしばらく待ってから再試行することです。しかし、ただ待っているだけでは十分ではありません。全員が同時に再試行すると、再び制限に達します。解決策は指数バックオフです。つまり、試行が失敗するたびに待機時間を指数関数的に増やします。
# 指数関数的バックオフ ロジック トライアル 1 → 429 → 1 秒待機 トライアル 2 → 429 → 2 秒待機 トライアル 3 → 429 → 4 秒待機 トライアル 4 → 429 → 8 秒待機 (+ 小さなランダムな「ジッター」)... 最大 N 回のトライアル後に諦めてレポート
これに少しのランダム性 (ジッター) を追加すると、同時に再試行しようとしたときにリクエストが衝突するのを防ぎます。さらに、429 応答には、「この秒数以内に再試行してください」という `retry-after` ヘッダーが含まれることがよくあります。このタイトルを尊重することは、盲目的に待つよりも正確です。
注意: 429 を受け取った場合、「さらにリクエストを送信して強制する」と状況が悪化します。制限は満たされ続けており、リクエストは通過しません。正しい反応は加速ではなく後退です。良いニュース: ほとんどの公式 SDK は、バックオフを使用して 429 エラーとサーバー エラーを自動的に再試行します。SDK を手動でインストールする前に、この SDK の動作を使用してください。
HTTPエラーコードの分類
すべての間違いが同じというわけではありません。重要な違い: 再試行できるのか、それともリクエスト/アイデンティティの問題なのか?
コード
意味
もう一度試すことはできますか?
正しい反応
400
無効なリクエスト(フォーマット/パラメータエラー)
いいえ
リクエストを修正します。同じものを再度送信しないでください
401
認証エラー(キーが無効/キーがありません)
いいえ
キー/タイトルを修正
403
権限なし (モデル/機能へのアクセスなし)
いいえ
権限/スコープを確認する
404
見つかりません (モデル ID/エンドポイントが正しくありません)
いいえ
正しいモデルID/アドレス
429
制限速度を超えました
はい
撤退+再試行後
500
サーバーエラー
はい
退却して再試行してください
529
サーバーが過負荷になっている
はい
退却して再試行してください
黄金律: 429、500、529 は一時的なものです。撤退で再試行されます。 400、401、403、404 はリクエスト/アイデンティティの問題です。やり直しても解決せず、無駄な労力がかかります。コードではこれら 2 つのグループを区別する必要があります。
ステップバイステップ: 永続的な通話
- リクエストを送信します。成功した場合は続行します。
- エラーコードを分類します。もう一度試すことはできますか?
- 試行可能な場合: retry-after に従い、指数バックオフ + ジッターを適用し、限られた回数 (最大 5 回など) を試行します。
- 試していない場合: (フォーマット/キー) を修正して停止します。ループ内で同じ誤ったリクエストを繰り返さないでください。
- 諦めることを考えてみましょう。 n 回試行してもまだ成功しない場合は、ユーザーに丁寧なメッセージを表示し、イベントを記録します (追跡ユニット 11)。
# 堅牢な呼び出し pseudo-codedene = 0repeat:response = request_at() if response.success: return request if response.code in [429, 500, 529] and try < 5: wait = retry_after ?? (2^試行秒 + ジッター) sleep(wait); += 1 を試してください。もう一度 git if response.code in [400, 401, 403, 404]: save_error(response); return "リクエストを修正する必要があります" return "永続的なエラー、後で試してください"
# ユーザーへの丁寧なフィードバック (再試行が限界になったとき) 「今忙しいので、リクエストを処理できませんでした。すぐにもう一度お試しください。または、リクエストを保存しました。準備ができたら折り返しご連絡します。」
弱いプロンプト / 強いプロンプト (ここでは、エラー メッセージのデザイン)
# WEAK (生のエラーをユーザーに表示)「エラー 429: rate_limit_error」
# STRONG (ユーザーフレンドリー、安心感、アクション提案) 「システムで一時的な輻輳が発生しました。リクエストを安全に受信し、自動的に再試行されています。数秒以内に結果が表示されない場合は、ページを更新してください。」
生の技術的エラーをエンド ユーザーに明らかにすると、信頼が損なわれ、セキュリティ上の脆弱性が発生する可能性があります。エラーを内部で分類し、ユーザーに冷静でアクション指向のメッセージを提供します。記録用に技術的な詳細を書くだけです。
ミニケース3個
ケース 1 — 交通爆発によりボートが墜落した。カスタマー サービス ボットは、キャンペーン当日に 429 件の急増トラフィックを受信しました。コードには再試行はなく、すべてのエラーは「エラー」としてユーザーに直接反映されました。彼らは指数関数的リトレースメント + リトライアフターを追加しました。同じトラフィックの場合、リクエストは数秒の遅延で通過しましたが、ユーザーにはエラーは見られませんでした。
ケース 2 — ループ内で 400 を試行します。統合では、無効なモデル ID が原因で 404 が返されましたが、すべてのエラーが「一時的」として扱われ、無限ループで再試行されていました。ログが肥大化して余計な負荷が発生してしまいました。彼らはエラー分類を追加しました: 404 は永続的なものとみなされ、ループが停止され、モデル ID が修正されます。教訓: すべての間違いをやり直す必要はありません。
ケース 3 — 正面から制限を管理する。データ エンリッチメント ジョブが常に 429 の制限で実行されていました。 x-ratelimit-remaining ヘッダーに従い、クォータに従ってトラフィックを抑制しました。そのため、彼らは 429 秒台を記録することなく、リミットぎりぎりの安定したペースを維持しました。作業はより予測可能かつ迅速に完了しました。
よくある間違い
- 429 で速度を上げると、状況が悪化します。撤退に切り替えます。
- 各エラーを再試行します。400/401/404 は永続的です。もう一度試すのは無駄です。
- 固定待機の使用: 衝突が発生します。指数関数 + ジッターを使用します。
- 「retry-after」を無視する: プロバイダーによって指定された時間に従うのが最も正確です。
- 生のエラーをユーザーに明らかにすると、信頼が揺らぎ、脆弱性が生じます。中を分類します。
- 無制限の再試行: 上限を設定します (例: 5 回の再試行)。それなら潔く諦めましょう。
さらに詳しく: キューイング、同時実行性、サーキット ブレーカー
一つの欲望を耐えることが最初のステップです。本当の成熟度は、制限に達することなく大量のリクエストを管理することです。ここでは 3 つの概念が関係します。
キュー: リクエストをキューに入れて、すぐに送信するのではなく、制御されたペースで送信します。キューを使用すると、突然のトラフィックの急増がスムーズになります。たとえ 1,000 件のリクエストが一度に到着したとしても、キューは制限を下回る速度でそれらのリクエストを解放します。こうすることで 429 を防ぐことができ、修正について心配する必要はありません。
同時実行制限: 同時に「送信中」のリクエストの数を制限します。無制限の並列リクエストは、RPM と TPM の制限をすぐに満たします。合理的な同時実行数の上限 (同時リクエスト数が 10 個以下など) は、制限を維持し、システムを予測可能にします。
サーキット ブレーカー: プロバイダーが 500/529 を返し続ける場合、すべてのリクエストを粘り強く試すのではなく、しばらくの間「サーキットを遮断」し、リクエストを送信せずにすぐに失敗させます。待った後、回路を再度オンにして試してみます。このパターンにより、プロバイダーに一時的な障害が発生した場合にシステムがクラッシュするのを防ぎます。
これら 3 つを組み合わせることで、単一呼び出しの再試行ロジックを超えたシステム レベルの復元力が確立されます。小規模な場合は、SDK の自動再試行で十分です。規模が拡大するにつれて、キューイング、同時実行性、サーキット ブレーカーが不可欠になります。これらはすべて同じ共通の目標を持っています。それは、一時的な問題をクラッシュとしてではなく、数秒の目に見えない遅延としてユーザーに反映することです。
要約すると
速度制限 (RPM/ITPM/OTPM) を超えると 429 が返されます。これは一時的なエラーであり、再試行後および指数バックオフ + ジッターを使用して再試行されます。 500 と 529 も暫定的なものです。 400/401/403/404 はリクエスト/アイデンティティの問題であり、再試行しても解決できません。堅牢なフローでは、エラーをこれら 2 つのグループに分け、制限回数を試行し、制限を正面から監視して、ユーザーに落ち着いたメッセージを表示します。
アプリケーションタスク
統合を検討してください。 (1) 発生する可能性のあるエラー コードをリストし、「再試行可能 / 永続的」に分けます。 (2) 指数関数的プルバック計画 (初期ホールド、係数、キャップ、ジッター) を書き留めます。 (3) retry-afterヘッダの使用方法を指定します。 (4) リトライが限界に達した場合にユーザーに表示する丁寧なメッセージを記述します。
チェックリスト
- [ ] RPM/ITPM/OTPM 制限と 429 について説明できます。
- [ ] 指数関数的後退 + ジッター + 再試行後のロジックを適用できます。
- [ ] エラー コードを再試行可能/永続的に分類できます。
- [ ] すべての間違いを試みるべきではないことはわかっています。
- [ ] 生のエラーの代わりに、落ち着いたアクション指向のメッセージをユーザーに表示できます。