TT Lab
はじめる
学ぶ 学習パス コース

冪等性 — 二度押しても決済は一度だけ

冪等なリクエストにも再試行の予算が必要:設計の考え方

TT Labで続きを見る

一言でいうと

リトライは「もう一度」ではなく、安全なリクエストを、残りの時間と回数の範囲内で再送するポリシーです。

なぜ必要なのか

遅いサービスにクライアントが一斉にリトライすると、すでに詰まったキューにリクエストがさらに積まれます。 リクエストごとのtimeoutを5秒にして3回試すと、全体の作業は5秒以内には終わりません。 最初に締め切り時刻を計算して、各呼び出しと待機の前に、残りの時間を改めて求める必要があります。 冪等キーがあっても、コスト・負荷・ユーザーの待ち時間までなくなるわけではありません。

どう動くのか

send(남은 시간) → 응답 → 재시도할 상태인가? → 재생해도 안전한가?
                                                ↓
종료 ← 횟수 또는 전체 예산 소진 ← 지터 + Retry-After 대기 계산
                                                ↓
                                            sleep → 다음 호출

このラボのポリシーは、429・502・503・504だけをリトライします。GET・HEAD・PUT・DELETEは、このAPIの 冪等の契約を前提に許可し、POSTは空でないキーがあるときだけ許可します。サーバーがそのキーを 実際にアトミックに処理していなければ、クライアントに文字列を付けるだけでは安全ではありません。 前の冪等性のラボが、まさにそのサーバー側の前提を扱います。

現場での姿

指数バックオフにジッターを加えると、すべてのクライアントが同じ時刻に起きる現象を減らします。 サーバーのRetry-Afterがローカルの待機より長ければ、より長い値に従います。全体の予算より長いサーバーの 待機を、勝手に縮めて早くリトライすることはせず、現在の応答を返します。ここでは整数秒の形式だけを サポートし、HTTPの日付形式はサポートしないという制限を明示します。

次のラボですること

偽の単調時計・sleep・sendで、実際に待たずに8つのステップを検証します。sendは、受け取った残り時間 以内に応答するアダプターだという前提です。同期関数が永遠にブロックされると、実行器は強制的に中断 できないので、実際のHTTPアダプターには、別にtimeoutの設定が必要です。予算と最大回数は、 最初の試行を含みます。すべての状態をリトライしたり、412の競合をネットワーク障害として扱ったりしません。

参考: HTTPの冪等メソッド