記一次奇葩接口

1.回傳接口要求

第一次遇到這麼奇葩的API接口回傳要求:

  1. HTTP Status爲500、1000、或者超時、響應慢都要重試
  2. 前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:這種反饋統計的一般都不會讓你點,往往是程序自己後臺默默去做的事情那事件就別暴露的那麼明顯了。就算是讓點的,那你至少把個按鈕變爲禁用狀態(可以多少時間後恢復)

解決多次請求的問題其實可以通過前後端來共同處理:(主要還是後端處理,前端是儘量避免和延緩)

  1. 比如UI層面的禁用和多長時間恢復
  2. 比如每個請求都可以帶上一個時間戳,後端只要看到時間戳超過5s/10s的直接拒掉了(超時拒絕響應
    1. PS:這個最簡單,尤其是對於服務器配置不高的情況。除了這種方法,還可以通過限流算法來處理
  3. 再比如前端在請求前搞個類似hash或者隊列的數據結構,同一個連接別陸續請求多次,後端類似於ResponseCache的東西,讓瀏覽器對相同請求進行緩存下
  4. 再比如後端通過各種緩存(eg:redis)、令牌桶之類的限流算法來處理

不扯了,先這樣

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章