產業脈動 2026 年 9 月 18 日

2026-09-18 — Uber 導入錯誤歸屬機制,讓重試不再互相放大

primary=https://www.uber.com/en-US/blog/protecting-against-retry-storms/ primary=https://www.uber.com/us/en/blog/automated-dependency-analysis/

Uber 導入錯誤歸屬機制,讓重試不再互相放大

Uber Engineering Blog · 2026-09-17

當呼叫鏈深處的一個服務開始出錯,上游每一層都各自重試,結果不是把問題壓下去,而是把流量一層層乘上去。Uber 在〈Protecting Against Retry Storms〉中,說明他們如何為每個服務標記這個錯誤是不是自己造成的,只讓真正該負責的一層重試,而不是整條鏈一起重試。

原本的問題

Uber 的服務網格裡,重試是預設行為,呼叫失敗就再打一次,看起來合理,但沒有人知道這個錯誤究竟從哪一層冒出來的。文章給出的模型是 R^d × NR 是每層的重試次數、d 是呼叫鏈深度、N 是原始請求量。以深度 3、每層重試 1 次為例,最底層服務收到的流量會被放大到 8 倍。

問題不在於重試次數不可控,那是每個服務自己設的參數,而在於重試的時機不可控:一個服務收到失敗回應時,無法分辨這是自己的錯,還是下游某個節點的錯誤只是路過它而已。結果是每一層都各自為政地重試同一個下游故障,故障服務等於同時被上面所有層級圍攻。

採用的方法

Uber 先用另一套系統(Service Dependency Analysis,2026-09-15 發布)替每一組呼叫關係算出一個機率:某下游節點失敗時,呼叫端也一起失敗的比例。機率 ≥0.8 判定為 fail-close(硬依賴)、≤0.2 判定為 fail-open(軟依賴),中間地帶標成未知。這個分類是後續判斷誰該負責的資料基礎。

在此之上,Uber 加入錯誤歸屬(error ownership)邏輯:一個服務只有在處理這次請求時,自己沒有任何下游呼叫失敗的情況下,才會認領這個錯誤,並透過 x-uber-error-claim 標頭往上游回報。呼叫端的重試中介層(retry middleware)只在收到已認領的錯誤時才觸發重試;如果錯誤其實是下游造成、只是路過這一層,呼叫端就不重試,把重試的責任留給真正出錯的那一層。至於同時失敗的巧合情況,Uber 的資料顯示在流量最大的邊上,呼叫端剛好也一起失敗的比例約 2%,屬於系統會另外用相關性判斷過濾的邊界案例。

實際效果

2025 年 11 月 18 日,Core Entity 服務在呼叫鏈深度 5 的位置發生故障,錯誤歸屬機制擋下了九百五十萬次本來會發生的多餘重試請求。文章指出,若沒有這套機制,故障服務承受的流量會再暴增 46% 到 135%,等於在故障當下火上加油。

指標導入前導入後
重試風暴最大擴散深度253
重試風暴平均擴散半徑202

這套機制目前已經全面部署在 Uber 的整個服務網格上。對其他跑微服務、client 端有自動重試邏輯的團隊來說,值得對照的是:重試次數、退避時間都好調,但如果沒有辦法分辨這個錯誤是不是自己造成的,重試設定得再保守,故障還是會被一層層放大。

原始來源:Protecting Against Retry StormsAutomated Dependency Analysis


End of article
0
Would love your thoughts, please comment.x
()
x