Open2

HTTPリクエストのリトライについて学ぶ

matsuyamamatsuyama

まずは一般的な戦略についてGPTに訊いた。


ウェブアプリ通信のリトライ戦略において重要なのは以下のポイントです:

  1. リトライの条件の定義:全ての失敗したリクエストをリトライするのではなく、特定のHTTPステータスコード(例:5xx系のサーバーエラー)やネットワークエラーが発生した場合に限定することが一般的です。
  2. リトライ回数の制限:無限にリトライするのは避け、適切な回数(例:3回)に制限することが重要です。これにより、サーバーへの過度な負荷やエンドユーザーの待機時間の増加を防ぎます。
  3. エクスポネンシャルバックオフ:連続してリトライする際は、リトライの間隔を指数関数的に増やす(エクスポネンシャルバックオフ)方法が推奨されます。これにより、サーバーが過負荷になるのを防ぎつつ、回復後の通信成功率を高めることができます。
  4. ジッターの導入:エクスポネンシャルバックオフに加え、リトライ間隔にランダムな変動(ジッター)を加えることで、サーバーに対するリクエストの集中を避けることができます。
  5. エラーハンドリングの工夫:リトライが最終的に失敗した場合には、ユーザーに適切なエラーメッセージを表示し、可能ならば代替のアクションを提案することが望ましいです。

エクスポネンシャルバックオフジッターは初めて見る単語。

エクスポネンシャルバックオフ

クラスメソッドの記事内の説明がわかりやすかった。

例えば、5秒間のネットワーク障害が発生したとして、1秒間隔で3回リトライしても全て失敗してしまいます。
一方、エクスポネンシャルバックオフは1秒、2秒、4秒、8秒…とリトライ処理の間隔を指数関数的に徐々に長くしてリクエストの成功率を上げることが狙いです。 上記の障害例に適用すると、3回目のリトライ処理で成功するため、固定値よりも成功する可能性が高いことがわかります(あくまでこの単純な例の場合においては)。

ジッター

ジッターはリトライの間隔に"ノイズ"(ランダムな時間の前後)を加えることで、失敗の原因がリクエストの競合にある場合を回避しやすくする方法。
1秒、2秒、4秒、8秒…とリトライしたとしても、競合するリクエストが同様の時間間隔でぶつかり続けるなら障害が起き続ける。これを防ぐためにエクスポネンシャルバックオフと併せて使われるよう。

matsuyamamatsuyama

リトライをするべきリクエストとそうでないリクエスト

基本的には5xx系エラーについてリトライを考える。

4xx系エラーはクライアントサイドに問題がある場合なので、何度リクエストしても同じ結果になるからリトライではない解決が必要。
一方で、401(unauthorized)の場合は、トークンの再取得やリフレッシュを挟むことで疑似的なリトライとしてハンドリングすることも可能そう。