テクノロジー

APIタイムアウト設計|待機と再試行の5つの判断

株式会社Atsumell|9分で読めます
APIタイムアウト設計と待機・再試行の5つの判断を示すサムネイル

はじめに

在庫照会APIが遅くなったので、タイムアウトを長くした。今度は画面の待機が終わらない。短く戻して再試行を増やすと、障害中のAPIへ要求が集中する。これは設計を考えるための例ですが、「何秒待つか」だけを決めても解消しない問題です。

APIのタイムアウト設計では、一回の通信を待つ時間と、業務操作全体が完了する期限を分けます。そのうえで、誰が、どの失敗を、残り何秒の範囲で再試行するかを合意します。本記事は特定言語の設定方法ではなく、発注側と開発側が仕様書に残す五つの判断を整理します。

タイムアウトとリトライは別の役割を持つ

タイムアウトは待機を打ち切る条件、リトライは要求を改めて試す処理です。AWSの公開解説は、接続と要求のタイムアウトを設け、再試行の間隔をバックオフとジッターで調整する考え方を示しています。ジッターとは、再試行が同時刻へ集中しないよう待機時間にばらつきを持たせることです。

ここで、クライアントが待つのをやめても、サーバー側の処理まで取り消されたとは限りません。また、同じ条件の再送が安全かどうかは、呼び出すAPIの契約に依存します。登録系の二重実行を防ぐ条件はAPIの冪等性と二重登録防止で確認し、本稿では「待ち方と試す量」に焦点を当てます。

仕様書で合意する五つの判断

1. 一回の通信より先に、業務全体の期限を決める

最初に、利用者が何を待っているかを書きます。在庫照会の画面なのか、翌朝までに終えればよい夜間処理なのかで、許容する待ち時間は異なります。「外部APIは一律三十秒」という設定から始めず、操作開始から画面へ結果を返すまでの総期限を置きます。

総期限には、認証、接続、送受信、再試行の待機、結果の整形も含めます。呼び出すたびに同じ長さのタイマーを作り直すだけでは、全体の待機が伸び続けます。処理を引き継ぐ箇所では残り時間を確認し、次の試行を始めてよいかを判断する設計にします。

期限内に終わらない処理は、受付後に状態を確認する非同期方式も候補です。ただし、受付済みを完了済みとは表示しません。画面操作とバッチを同じ設定にまとめず、操作別に「いつまでに、何を返すか」を決めるのが出発点です。

2. 接続・読み取り・総期限の計測範囲を区別する

設定名がtimeoutでも、何を測るかは同じとは限りません。接続確立までなのか、応答データが届かない時間なのか、要求開始から終了までなのかを、使用するクライアントの公式仕様で確認します。AWSの解説も、DNSやTLSの処理がタイムアウトの範囲に入らない実装への注意を挙げています。

仕様書には設定値だけでなく、開始点、終了点、含まれない処理を記載します。接続を再利用する場合と、新しく接続する場合も試験条件に分けます。普段は速いのに起動直後だけ失敗するなら、同じ条件を測れているかを見直す必要があります。

値を選ぶ材料は、対象処理の応答時間の分布と業務上の許容時間です。平均値だけでは遅い要求を見落とすため、遅い側の分布も確認します。測定がない段階では仮の値、決定担当、計測方法、見直し条件をセットで残し、「一般的な推奨秒数」を自社の保証値にしないでください。

3. 再試行する層と、再試行しない条件を固定する

アプリが再試行し、SDKも再試行し、さらにジョブ基盤が再実行すると、実際の送信回数が仕様書から見えなくなります。どの層が責任を持つかを一つずつ確認し、設定を重ねる前に物理的な送信回数を計測します。

Google SREの過負荷対策では、要求単位とクライアント単位の再試行予算を分け、多層の再試行による増幅も扱っています。掲載された回数や割合をそのまま流用するのではなく、自社の呼び出し経路でどこが止めるかを決める材料にできます。

再試行候補は、APIが一時的な失敗として定義するものに限定します。入力不備、権限不足、業務上の拒否を、同じ要求の連打で解決しようとしません。登録結果が不明なら、冪等性や状態照会の契約を確認するまで無条件に再送しない方針も必要です。エラーごとの次の行動はAPIエラーレスポンス設計と対応させます。

SDKの既定値は、言語、版、モードによって確認が必要です。AWS SDKの公式ガイドにも、新しい挙動へのオプトイン条件と設定の優先順位が記載されています。「SDK側でよしなに再試行する」ではなく、利用版と実効設定を検証記録へ残しましょう。

4. 待機時間・総試行回数・残り時間を一緒に制限する

再試行の最大回数だけでは、負荷も待機時間も決まりません。バックオフの初期値と上限、ばらつきの範囲、初回を含めた総試行回数を記載します。「三回リトライ」が初回と合わせて何回になるかも、言葉ではなく回数で明示します。

以下は、参照系APIの設計検討用の例です。特定サービスの推奨値ではありません。

項目合意内容の例
操作全体の期限開始から八秒
一試行の上限接続を含め最大二秒。総期限の残りを超えない
総試行回数初回を含め最大三回
再試行前の待機一回目は最大二百五十ミリ秒、二回目は最大五百ミリ秒の範囲でばらつかせる
終了処理の余裕結果の整形と応答のため一秒を確保
新しい試行の開始条件待機後に、次の試行と終了処理の時間が残っている

この例の上限時間を足すと七・七五秒です。ただし、認証など別処理があるなら同じ予算へ追加し、実測で確認します。前の処理が長引いて残り時間が足りなければ、回数が残っていても次の要求を送りません。

提供APIが待機時間を案内する場合も、自社の総期限との整合を確認します。指定された待機が期限を超えるなら、同期操作内で待ち続けず、保留や非同期化の契約へ切り替えます。短い間隔へ勝手に変更して提供側の制限を無視してはいけません。

5. 期限後の状態・利用者への案内・確認担当を決める

タイムアウト後の画面を、単に「失敗しました」で終わらせないようにします。参照結果を取得できなかったのか、登録の成否が不明なのかで、利用者が取るべき行動は違います。後者で新規登録ボタンを繰り返し押させる案内は避けたいところです。

操作ID、試行番号、経過時間、停止理由、対象APIを記録し、利用者へ示す問い合わせ番号と結び付けます。一方、認証情報や個人情報をログへそのまま残さないルールも決めます。状態照会へ移る場合は、その照会にも期限と権限を設け、照会失敗を「対象なし」と読み替えません。

結果を確認できないまま期限を迎えたときは、誰が何を照合するかを明記します。自動処理を止めることと、業務が取り消されたことは別です。キャンセルを送る設計でも、キャンセルの受付と処理停止の確認を分け、確かめられなかった状態を残します。

受け入れテストで待機の上限を確かめる

仕様を読むだけでなく、試験環境で遅延や応答の欠落を作り、時刻と送信回数を記録します。正常時の速度と、障害時にどこで止まるかを別々に検証しましょう。

  • 接続が成立しない場合と、接続後に応答が遅い場合を分ける
  • 新規接続と接続再利用で、タイマーの範囲を確認する
  • SDKの内部再試行を含め、総送信回数が合意値を超えないか測る
  • 待機中に総期限へ近づいた場合、次の試行が開始されないか確かめる
  • 同時に失敗した複数クライアントの再送が、特定時刻へ集中しないか見る
  • サーバー処理は完了したが応答だけ失われた場合、未実行と誤表示しないか確認する

記録するのは、最終的に成功したかだけではありません。総経過時間、各試行の開始と終了、待機時間、期限後の業務状態まで揃えて、仕様と実際の挙動を比べます。異常系の期待結果もAPI仕様書と同じ管理対象にします。

まとめ:秒数ではなく、待機から停止までを仕様にする

APIのタイムアウト設計は、業務全体の期限、タイマーの範囲、再試行する層、待機と回数の予算、期限後の対応を一組にすると検証しやすくなります。まず一つの外部連携を選び、上の表へ現在の実効設定を書き込んでください。説明できない空欄が、実装前に合意すべき事項です。

こうした例外条件が議事録や既存資料に散らばっている場合は、上流工程AIワークスペースKakusillの紹介もご覧ください。要件定義や仕様管理を支える製品であり、通信の再試行制御を自動で保証するものではありません。業務フローからAPIの停止条件や受け入れ基準を整理したい方は、Atsumellへのお問い合わせからご相談ください。

#API設計#タイムアウト#リトライ#非機能要件#要件定義