重試、退避與抖動(避免雷群)

★★★★★Draft

FromSRESRE Workbook

📚 From the Books

重試、退避與抖動(避免雷群)Reliability Patterns

重試是把雙面刃:下游只是抖一下時它救場,下游真的過載時它火上澆油。天真的「立即重試 + 固定退避」會讓客戶端同步化,掀起遠超尖峰的雷群(thundering herd)。安全的重試是「加抖動的截斷指數退避 + 重試預算 + 下游能喊停」。

🧠 Intuition

TIP

真實教訓(Pokemon GO):客戶端「單次立即重試後固定退避」在大規模故障時同步化,產生高達平時峰值 20 倍的請求尖峰。修法是引入 jitter(抖動)+ 截斷指數退避,把重試在時間上打散。

⚖️ Tradeoffs

重試預算(retry budget)— 給重試設天花板
  • Per-request budget:單一請求最多重試 ~3 次,避免個別請求無限打。
  • Per-client budget:整個客戶端的重試量不超過總請求的 ~10%——如此即使整個 DC 都壞,總負載也只放大約 1.1 倍而非 3 倍。
  • 判斷情境:少量後端過載(較常見)→ 重試多半打到別的健康 task,有用;大部分後端都過載 → 重試沒用,讓錯誤直接上傳給使用者。
  • 別把「重試」當免費補救——它消耗的是本就稀缺的過載容量。
讓下游能「喊停」— overloaded; don't retry
  • 客戶端在請求 metadata 帶上「已嘗試次數」;backend 若看到很多 high-attempt 請求,代表重試正在放大災情。
  • 此時 backend 改回傳特殊錯誤「overloaded; don’t retry」,明確要求上游停止重試、改走降級或直接失敗,阻斷組合爆炸。
  • 搭配 deadline:對使用者已無益的請求該及時放棄,別為它持有資源、也別再為它重試。
  • 與熔斷器分工:退避管「單次別打太密」、熔斷管「整體先別打了」——兩者常一起用。

🔑 Takeaways

✍️ My Notes

No notes yet — jot your takeaways or Q&A here.

📖 Further Reading

🔗 Dive Deeper