一千萬個為什麽

搜索

如何避免分布式服務中的“重試風暴”?



當客戶端被配置為在放棄之前重試設定的次數時會導致“重試風暴”,因為在服務的正常操作中將發生分組丟失,所以需要重試策略。

以這個例子:

Sample Architecture

例如,如果整個服務的規模擴大到每秒支持80,000個請求並以大約80%的容量運行,那麽導致該服務每秒接收101,000個請求的流量激增將導致1,000個請求失敗。

當重試策略開始時,您最終會獲得額外的1,000多個請求,具體取決於檢測到失敗的位置,從而將服務整體推到每秒102,000個請求 - 從那裏您的服務進入死亡螺旋,使數量翻倍每秒失敗的請求數。

除了預計的高峰交易之外的大規模超額配置服務,這將是低效的。你可以采用什麽策略來避免“重試風暴”?

轉載註明原文: 如何避免分布式服務中的“重試風暴”?

一共有 2 個回答:

這取決於你想要避免的。

如果您試圖避免任何服務中斷,而這些服務是真正關鍵的服務(我在考慮“如果我的API調用沒有得到適當的服務,人們會死亡”),那麽您需要預算來處理巨大的低效率問題來自大量配置專用資源。是的,他們必須是專註的,這不允許交通峰值的東西,多個服務扣球會因此導致中斷。

在 更有可能的情況下,服務停止不便,您可以從客戶端和服務器端解決問題。雖然值得註意的是,在邏輯上不可能真正解決流量過大的問題,因為如果不處理流量(消耗資源),您無法知道它是否是重試,如果重試了成功但未正確處理的請求由客戶端,如果它是一個DDOS等,但你可以減輕影響。

客戶端代碼中編寫明智的重試邏輯,它具有上限和正常失敗的機制。這樣,你就不會讓用戶陷入無限循環的失敗請求中,你只是給他們一個錯誤,告訴他們嘗試他們剛剛做的一切。

對於您的服務器端基礎設施,最簡單的解決方案就是節流。對請求有嚴格的限制,特別是如果你可以根據你的特定用例在邏輯上進行嘗試和傳播(例如,如果你有一個集中的服務做出一些艱難的決定,你是否想要阻止可能導致線程懸掛的地理上遙遠的請求服務器端?還是你想平均分配你的不可避免的輕微中斷?等等)它基本上歸結為從網關故意返回503是比讓請求通過並發送504無論如何。基本上強迫客戶根據您當前提供的內容采取行動,並提供正確的答案,以便客戶做出適當的反應。

防止這些重試風暴的一種方法是使用退避機制。

從Google應用服務引擎的實施退款重試部分規模設計指南:

無論是否調用服務,您的代碼都可以在失敗時重試   雲數據存儲或使用URL提取或套接字的外部服務   API。在這些情況下,您應該始終實施隨機化   指數退避政策,以避免雷鳴群峰   問題的。您還應該限制重試的總次數   在達到最大重試限制後處理失敗。

大多數GAE API已經默認啟用了這種退避機制/策略。