连载中 14/18

超时与重试:三态结果的不确定性

2026-06-21 · 4501 阅读 · 0 评论 · 0 赞

一笔钱处理了两遍

老王复盘一笔诡异资损:支付服务调渠道超时(超时设 5 秒),按失败处理给用户发了退款;渠道那边其实在第 6 秒扣款成功了。结果渠道扣了一笔,平台退了一笔——超时被当成了失败,这是分布式系统最经典也最贵的一类误判。本篇把超时与重试的纪律一次讲清。

超时是三态:成功、失败、未知

第 1 篇立过规矩:远程调用有第三态。超时永远不等于失败——超时只说明「响应没在约定时间回来」,不说明「业务没执行」。请求可能还在下游队列里排着,可能已经执行成功只是响应包丢了。把超时当失败的每一行代码,都埋着一笔双重处理的雷。

未知态的处理纪律只有一条:不猜,先查询。超时后调下游的查询接口(按流水号查这笔处理到哪了):查到成功,按成功走;查到失败,按失败走;暂时查不到,保持未知状态挂起,定时再查——实在查不出来的,进对账系统兜底(第 16 篇)。宁可慢,不可错。

超时时间怎么定

太短——下游正常处理就被误判,退款的雷一个接一个;太长——上游线程被吊住,故障时连接池被拖垮(第 14 篇分布式 ID 高可用的教训同源)。经验值:取下游正常耗时 P99 的两到三倍,并区分连接超时(建连,几百毫秒)与读超时(等响应,按业务)。更重要的是监控超时率——超时率突增说明下游病了,该触发的是熔断与告警,而不是让每个请求都傻等满超时。

重试的四条纪律

纪律一:只重试「确定没生效」的请求。连接被拒、DNS 失败这类「请求根本没到」的失败,可以放心重试;超时类的未知态,重试之前先走查询确认——除非操作天然幂等且业务容忍重复(查询类请求随意重试)。

纪律二:重试的前提是幂等。第 10 篇的五大武器就是为这一刻准备的——没有幂等兜底的重试,等于主动制造重复扣款。

纪律三:指数退避加抖动。失败后等 100 毫秒再试、再失败等 200、400……间隔翻倍,且每次加入随机抖动(比如在退避值上浮动 20%)。没有抖动的固定间隔重试,会让所有实例在同一毫秒齐射——重试风暴:下游抖了一下,全体上游的 QPS 瞬间翻倍,本来能自愈的小故障被重试压成彻底瘫痪。

纪律四:设重试预算。单链路重试次数封顶(比如最多两次),全服务重试流量占比封顶(比如 10%)——超预算直接快速失败。重试是放大器,没有预算的放大器迟早烧掉整个系统。

一次正确的超时处理

调渠道扣款 → 读超时(5s,P99 的 2.5 倍)
  ↓ 未知态,不猜
按流水号查询渠道 → 返回「处理中」
  ↓ 保持挂起,30 秒后定时再查
返回「成功」→ 落成功状态,业务继续
(若最终查不到 → 挂起单进对账,人工兜底)

熔断:比重试更高一级的刹车

超时率持续走高时,重试只是给病人做心脏按压,熔断才是停止压迫先止血:错误率过阈值后一段时间内直接快速失败(不再傻等超时),半开状态探活恢复后才放流量回来。配合舱壁隔离(按下游隔离连接池,一家故障不拖垮全部),就是 resilience4j、Sentinel 这类组件的日常工作。分布式事务链路上,每个远程跳点都要有超时、重试、熔断三件套——少一件,故障就会顺着调用链放大。

小结

超时重试一句话:超时是未知态不是失败,先查询后行动;重试四纪律——只重试确定未生效、幂等打底、退避加抖动、设预算;熔断是高一级的刹车,三件套缺一不可。链路上单点的纪律齐了,但很多事故的根不在远程调用,而在本地事务里偷偷干了不该干的事——下一篇:@Transactional 的七宗罪。

503

10 年全栈工程师 · 503咖啡馆主理人

#分布式事务#超时#重试#熔断#三态

评论 (0)

相关推荐

连载中 12/20

排查四件套:jstack、jmap、jstat、jcmd 的实战分工

jstack 看线程在干什么,jmap 看堆里装了什么,jstat 看运行时在变什么,jcmd 是统一入口。四把刀各管一段,配合着用没有查不动的现场。

#jstack#jmap#jstat#jcmd#排查工具
2026-09-16 · 4 阅读 · 0 评论 · 0 赞
连载中 11/20

GC 日志:把回收过程翻译成人话

一行 GC 日志里塞着七种信息:谁触发的、收了哪、停了多久、活了哪些。加上 -Xlog 配置,再加上日志分析工具,GC 不再是只能盯监控曲线的黑盒。

#GC日志#Xlog#日志分析#GC监控#Full GC排查
2026-09-16 · 13 阅读 · 0 评论 · 0 赞
连载中 10/20

ZGC:亚毫秒停顿是怎么炼成的

百 G 大堆停顿不到一毫秒,靠的是把搬家全部挪到并发阶段——着色指针让引用自带状态,读屏障让搬运中的对象依然可访问。代价是吞吐与内存,收益是停顿与堆大小解耦。

#ZGC#着色指针#读屏障#亚毫秒停顿#分代ZGC
2026-09-15 · 8 阅读 · 0 评论 · 0 赞