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が、今日も元気にパケットを届け続けられますように! また次の技術の深淵でお会いしましょう。
コメント