【入門編】 APIゲートウェイでのリクエストタイムアウトと再試行(Retry)戦略 – Web APIアーキテクチャ・データ連携実践ガイド

APIの「迷子」を防ぐ!APIゲートウェイでのタイムアウトとリトライの賢い設計術

こんにちは。ネットワークとプロトコルの深淵を旅するアーキテクトです。

Web APIを作っていると、必ず直面する壁があります。それは「相手からの返事がなかなか来ない」という状況です。ネットワークの世界では、パケットは光の速さで飛んでいきますが、バックエンドの処理が重かったり、一時的に混雑したりすると、まるで郵便物が届かないかのように応答が滞ります。

今回は、そんな「返事がない!」というピンチをどう乗り切るか、APIゲートウェイにおけるタイムアウトとリトライ(再試行)戦略について、身近な例えを交えてお話ししましょう。

—

1. 「返事がない」はいつまで待つべき?(タイムアウトの考え方)

あなたが郵便で重要な書類を送ったとします。相手から1日経っても返事が来ない……。これは「配達中」なのか、「相手が忙しくて封すら開けていない」のか、それとも「郵便事故で紛失した」のか分かりませんよね。

APIゲートウェイ(APIへの入り口となる門番)も同じです。バックエンドのサービスにリクエストを投げてから、いつまで待つかを決めるのが「タイムアウト」です。

  • 短すぎると: 本来なら処理できたはずの重いリクエストまで「返事がない!」と切り捨ててしまいます。
  • 長すぎると: ダメなものは早く諦めてほしいのに、ずっと待ち続けてしまい、APIゲートウェイ自体が「渋滞」を起こしてパンクしてしまいます。

現場では、このバランス感覚が非常に重要です。まずは「この処理は通常何秒で終わるのか?」を計測し、その1.5倍〜2倍程度を「妥協ライン」として設定するのが鉄則です。

—

2. 「もう一度送る」の勇気とリスク(リトライ戦略)

返事がないとき、反射的に「もう一回送ればいいや!」と考えがちです。しかし、これがネットワークの世界では「諸刃の剣」になります。

例えば、決済APIにリクエストを送ったとしましょう。
1. あなた:「決済してください!」
2. サーバー:「了解、処理中……(ここで遅延)」
3. あなた:(タイムアウト!)「返事がないからもう一度送ろう!」
4. サーバー:「また決済依頼が来た!二重決済だ!」

このように、「もう一度送っても安全な処理」と「送ってはいけない処理」を見極める必要があります。これを専門用語で「冪等性(べきとうせい)」と呼びます。

  • 冪等性がある: 検索やデータ取得、データの「上書き保存」など。何度送っても結果が同じならリトライOK!
  • 冪等性がない: お金の支払い、データの追加(重複作成)など。リトライには注意が必要です。

—

3. 賢い再試行の作法「指数バックオフ」

もしサーバーが「今、超混雑してるから少し待って!」と言っている時に、間髪入れずリトライを繰り返したらどうなるでしょうか? そう、サーバーに追い打ちをかけて「とどめ」を刺してしまいます。

これを防ぐのが指数バックオフです。リトライの間隔を徐々に長くしていくテクニックです。

  • 1回目:1秒待つ
  • 2回目:2秒待つ
  • 3回目:4秒待つ
  • 4回目:8秒待つ

郵便で例えるなら、「すぐ再送」するのではなく、「1時間後に送ってみよう」「次は半日待ってみよう」と、相手の状況を思いやって間隔を空けるのと同じです。

—

4. 実践:APIゲートウェイの設定例

実際に、APIゲートウェイ(ここではNginxのようなリバースプロキシを想定)で、どのようにタイムアウトとリトライを設定するか見てみましょう。

# APIゲートウェイの設定例
location /api/ {
    # 接続・送信・受信のタイムアウトを5秒に設定
    proxy_connect_timeout 5s;
    proxy_send_timeout 5s;
    proxy_read_timeout 5s;

    # エラーが発生した際のリトライ設定
    # サーバーがエラーを返したり、接続が切れたら最大2回まで再試行
    proxy_next_upstream error timeout http_500 http_503;
    proxy_next_upstream_tries 2;
    
    # 実際のバックエンドサーバーの指定
    proxy_pass http://backend_server_group;
}

コードのポイント:

  • proxy_read_timeout:バックエンドが処理を終えてデータを返してくるまでの「待ち時間」です。
  • proxy_next_upstream:どのような失敗をした時に「あ、ダメだ、別のサーバーに振ろう(またはリトライしよう)」と判断するかを指定します。http_500などを入れることで、サーバー内部でエラーが起きた際にも自動で救済を試みることができます。

—

まとめ:ネットワークは「思いやり」から

APIの設計において、タイムアウトやリトライは単なるパラメーターの設定ではありません。「限られたリソースの中で、いかにユーザーに快適な体験を届けるか」という、システムに対する思いやりそのものです。

「とりあえずリトライすればいいや」ではなく、「このリクエストは失敗したらどうなるか?」「バックエンドに負荷をかけすぎていないか?」と一歩立ち止まって考えることが、堅牢なシステム構築への近道です。

皆さんのAPIが、今日も元気にパケットを届け続けられますように! また次の技術の深淵でお会いしましょう。

コメント

タイトルとURLをコピーしました