Uber 如何终结重试风暴
How Uber Protects Against Retry Storms
重试风暴是分布式系统的噩梦,一次局部故障可能因盲目重试引发多米诺骨牌效应,导致全站瘫痪。Uber 发现,传统的手动配置重试预算缺乏上下文感知,无法区分错误是服务自身产生还是下游传递。为此,Uber 在共享基础设施中引入了一套基于错误归属(Error Ownership)的机制。通过 Service Dependency Analysis Solution 关联入站与出站失败,系统能精准判断错误源头:若服务自身出错则认领错误,若由下游引发则拒绝重试。这种上下文感知的策略有效阻断了错误的级联放大,既避免了在过载服务上无效重试,又保证了真正需要恢复的请求获得重试机会,从而在复杂依赖链中守住系统稳定性。
一个局部的故障如果处理不当,会迅速升级为影响整个服务栈的事故,最终导致终端用户体验的严重下降甚至完全中断。
HN 评论区
47- whatever1
很简单。每次重试,就从司机那里多扣一点。
- prologic
所以,本质上如果 A → B → C → D 且 D 失败了,C 可能会重试 D,但 B 和 A 会被劝阻不要重试整个链路。
这招挺聪明的。我也很喜欢“错误预算”(Error Budget)这个概念,毫无疑问是受 SRE 和 SLO 的启发 :)
- Scoundreller
与此同时,Google 不断给我弹出“请稍候,请勿刷新页面”的提示墙,于是我就尽可能快地按 ctrl-r。还是说,这就是对人类反应能力的测试?
- maxchisto
我对文章中未提及的负载 shedding(load shedding)持怀疑态度。如果在调用方结合指数退避(exp backoff),你就能得到一个相当稳健的起点。
- aftbit
我很想听听这个领域里的其他策略。我曾经天真地允许在所有地方重试,结果陷入了重试风暴。当这个问题再次出现时,我尝试了另一种天真的做法:只允许最顶层的服务重试,结果导致每次失败都要重做大量工作。有没有一条不错的中间路线,既不过于复杂又能解决问题?