I2.13.1retry with backoff设计
自动重试需要退避间隔而非立即连续重试加重服务器负担
别名: 指数退避 · 不要连打 · exponential backoff
概念解释
失败之后系统可以自己再要一次,不必每次都把人拉进来。自动重试若在失败的同一拍立刻再发、再失败再发,会把一次故障放大成一串同步的锤击:所有客户端同时打同一扇已经撑不住的门。退避(backoff)把下一次尝试推开——通常越来越长,并加一点抖动——让重试成为恢复的采样,而不是雪崩的燃料。
机制
瞬时故障(丢包、短暂 503、切换网络)值得再试,因为下一拍通道可能已经好了。立刻连打假设「越快试,好得越早」,在单机上看似合理,在群体上是同步化:同一秒失败的一万个客户端变成同一秒的一万次重试,服务器刚要喘,潮又到。退避把相位打散,间隔随次数变长,给对端和网络一条冷却曲线。抖动(jitter)防止大家用同一条指数曲线再次对齐。
退避也保护本地。主线程、无线电、电池会被连打拖进忙等;人看见的是失败皮在闪,其实是客户端在打自己。间隔让失败呈现稳定一会儿,自动重试在背后按时刻表走,而不是把界面当成连点器。
边界
幂等读可以退着再试;非幂等写(付款、创建)自动重试可能双花,要先有幂等键,否则不要自动。4xx 里明确的客户端错误(400、403、404)再试不会变好,退避只是礼貌地重复错误,应直接停。用户正在看的交互式失败,第一次自动可以短,但总预算要有上限,否则人会觉得产品在背后不停地撞。离线探测到的失败,退避到宇宙尽头也没有网,应改听网络恢复事件,而不是空转间隔。
怎么落地
- 自动重试走指数(或至少递增)间隔,加抖动;禁止失败回调里同步立刻再 fetch。
- 只对可能瞬态的失败码自动退:超时、429、502/503。鉴权失败和「找不到」不进这条队列。
- 写操作没有幂等键就不要自动重试。
- 验证:把服务端打成持续 503,看客户端时间线。若每 50 毫秒打一次直到打满,就是连打。改成带抖动的退避后,请求应疏开,且同批客户端不应在同一秒再次对齐。