开端:
接口重试这个话题对于开发同学很重要,而且重试的技术方案都很成熟,实现手段也各有千秋,不同的场景都有相对成熟的方案,首先得自己想清楚重试的目的是什么?不要为了实现重试而去做一些毫无意义的事。
背景:
C端特别是移动端⽤户⽹络环境错综复杂,因为⽹络抖动、服务抖动等原因导致接⼝请求失败的情况时有发⽣,因此部分场景会通过重试策略来尽可能保证接⼝调⽤成功,但是重试策略的实现各团队之间也互有差异,稍有不慎就有可能导致频繁重试甚⾄死循环进⽽加剧服务端压⼒,引发线上事故,因此针对重试策略我们给出了以下建议供⼤家参考。
建议⼀:不要在请求失败之后⽴即发起重试
原因如下:
1、如果是端上⽹络原因导致的失败,在不切换⽹络环境的前提下,⽴即重试的成功率⼏乎为0
2、如果是后端服务导致的失败,在短时间内恢复的可能性不⼤,此时盲⽬重试反⽽会加剧服务端压⼒
建议⼆:重试次数设置上限
任何的重试都需要设置次数上限,禁⽌将接⼝成功作为重试终⽌的唯⼀条件,死循环往往是由于失败即重试导致的,建议重试次数不超过3次
建议三:重试间隔递增
在有限的重试次数之内,建议每次重试的间隔不要固定,⽽是采⽤递增的策略:例如第⼀次重试间隔是3s,则第⼆次重试间隔为6s,第三次为9s,这样可以在不加⼤服务端压⼒的前提下最⼤化的保证重试的成功率
建议四:有选择性的重试
并⾮所有的失败都需要重试,下⾯⼏种情况是没有必要重试的:
1、由于上层主动调⽤cancel导致的失败在业务侧是符合逻辑的表现,这种不需要重试
2、404错误,这种由于url本身不正确导致的错误即使重试也是相同的结果
3、DNS解析失败,这种如果还是⽤相同的域名重试的话依然会解析失败
4、其他业务接⼝约定的⽆需重试的场景
建议五:重试交给⽤户
逻辑依赖接⼝结果返回的场景不要使⽤静默请求,尽可能的将重试能⼒暴露给⽤户,让⽤户侧决定是否重试
其他建议
1、要规避潜在的业务级别的循环,例如加载页面A,页面A需要刷新接口B,接口B如果失败或者异常的逻辑下存在刷新页面A的逻辑
2、端上在debug阶段添加同一个接口短时间多次调用的告警逻辑,尽可能将这种不规范重试提前暴露
3、重试次数最大上限建议网络库底层控制
4、如果业务有限流需求,建议重试策略由服务端控制,以便针对特定场景做更灵活的控制
希望各位多多指教,及时更新。