1. 程式人生 > 其它 >Linux | alias 命令別名

Linux | alias 命令別名

為什麼寫這個題目呢?

因為之前寫的一個 Node 程式有點小問題,使用的 axios 通過代理請求資料,代理伺服器(阿布雲)時不時抽風(407、413、503)。

因為第一次寫的時候當做一個 DEMO 去實現的,寫的挺簡陋,只能說大體功能對,但是沒有容錯機制

這裡我們先算一筆帳啊,一次請求等於 1+100 次,因為我內部還會請求好多資料。

如果只是第一次失敗了,那麼無關緊要,大不了重發一次。

但是如果是後面 100 次中有極個別暴雷了,那麼就會導致整個101次請求全部作廢。(因為返回的資料是錯誤的,使用者會觸發第二次請求。不止加重了伺服器的壓力,還增加了使用者檢查的壓力

好了,為什麼實現這個功能說了,那麼我們要開始實現了。

axios 發起請求

axios 發請求還是很簡單的,那麼我們可以直接仿照他來實現一下封裝。

axios({
    url: 'https://www.lilnong.top/cors/axiosAutoTry',
    params: 'user=sf',
    method: 'get'
})
.then(console.log)
.catch(console.log)

https://www.tmojm.com 創業加盟網

實現自動重試

我直接在data上增加一個__try_count用於設定重試次數。

因為 Axios 是支援 Promise,所以我們的方法也支援。
axios 如果成功了我們也 resolve。
axios 如果失敗了我們先判斷次數,然後根據具體的錯誤,進行重試。

  • 407 就是我理解的抽風
  • 413 是請求併發太高,為了不佔用多少可以加個延時器。
  • 503 也是我理解的抽風
  • ECONNABORTED很奇怪好好的資源他也不載入就卡住了,所以我設定了 timeout
  • ECONNRESET也是一個很奇怪的錯誤。(既然是 Node,我理解他經常出錯誤。)
function axiosAutoTry(data){
    return new Promise((resolve, reject)=>{
        axios(data)
        .then((data)=>{
            resolve(data)
        })
        .catch(error=>{
            // 有重試次數
            if(typeof data.__try_count == 'number' && data.__try_count>0){
                console.error('重試請求', error.message, data)
                data.__try_count--;
                if(error.code == 'ECONNABORTED'){
                    // 中止,超時
                    return resolve(axiosAutoTry(data))
                }else if(error.code == 'ECONNRESET'){
                    // 
                    return resolve(axiosAutoTry(data))
                }else{
                    if(error.response && error.response.status == 407){
                        // 代理407
                        return setTimeout(v=>{
                            resolve(axiosAutoTry(data))
                        }, 500 + Math.random() * 500)
                    }else if(error.response && error.response.status == 503){
                        // 伺服器異常
                        return setTimeout(v=>{
                            resolve(axiosAutoTry(data))
                        }, 1000 + Math.random() * 500)
                    }else if(error.response && error.response.status == 429){
                        // 併發超過限制
                        return setTimeout(v=>{
                            resolve(axiosAutoTry(data))
                        }, 1000 + Math.random() * 1000)
                    }
                    // console.error('異常錯誤', error)
                }
            }
            reject(error)
        })
    })
}