记一次奇葩接口 ~ 失败重试12小时
1.回传接口要求
第一次遇到这么奇葩的API接口回传要求:
- HTTP Status为500、1000、或者超时、响应慢都要重试
- 前10分钟每30s重试一次。后续每5分钟重试一次。如果12小时还未成功直接丢弃数据
你说数据重要嘛,你后面又不要了,说不重要嘛12h的重试。。。所以避免折腾,所有丢弃的数据还是得本地记录下日志
2.思路历程
一开始是用定时任务来处理,后来说太麻烦,让前端解决。。。
得写个计时器完事。后来又说逻辑太复杂,要简单便于维护。。。
那好,直接使用axiosRetry
,咱们也不搞啥算法了,就给它指定一个自定义的retryDelay
函数
也不要那么多复杂逻辑了,直接给您算好大概重试多少次,比如说:
// 添加axios-retry插件,配置重试策略
axiosRetry(jdRetryAxios, {
retries: 100, // 重试次数:差不多得了,它让你24h你还真24h重试不成?
retryDelay: (retryCount) => {
console.debug('retryCount:', retryCount);
if (retryCount <= 19) { // 前10分钟,每30s重试一次 ==> 20次
return 30000; // 30 * 1000;
} else { // 后续重试时间间隔每次间隔5分钟,最长12小时 ==> 144次
return 300000; //5 * 60 * 1000;
}
},
shouldResetTimeout: true, // 每次重试都重置超时时间
// 自定义条件,针对状态为500、1000、超时、网络问题进行重试
retryCondition: (error) => {
console.debug('retry touch:', error);
return error?.response?.status === 500 || // JD服务器内部错误
error?.response?.status === 1000 || // JD服务器内部错误
error?.code === 'ECONNABORTED' || // 后端响应超时
error?.code == 'ERR_NETWORK'; // 网络异常
},
});
3.潜在风险
但这种其实有2个潜在的问题:
1.有些请求其实只是响应超时,并不代表服务器没有响应
PS:等它来得及的时候就会一下把你之前的重试都响应给你了,你得鉴别,eg:token、timestamp
2.客户端可能会多次post请求,那你就要想办法去重
PS:这种反馈统计的一般都不会让你点,往往是程序自己后台默默去做的事情那事件就别暴露的那么明显了。就算是让点的,那你至少把个按钮变为禁用状态(可以多少时间后恢复)
解决多次请求的问题其实可以通过前后端来共同处理:(主要还是后端处理,前端是尽量避免和延缓)
- 比如UI层面的禁用和多长时间恢复
- 比如每个请求都可以带上一个时间戳,后端只要看到时间戳超过5s/10s的直接拒掉了(超时拒绝响应)
- PS:这个最简单,尤其是对于服务器配置不高的情况。除了这种方法,还可以通过限流算法来处理
- 再比如前端在请求前搞个类似hash或者队列的数据结构,同一个连接别陆续请求多次,后端类似于ResponseCache的东西,让浏览器对相同请求进行缓存下
- 再比如后端通过各种缓存(eg:redis)、令牌桶之类的限流算法来处理
不扯了,先这样
作者:毒逆天
打赏:18i4JpL6g54yAPAefdtgqwRrZ43YJwAV5z