我們調(diào)用的每個(gè)遠(yuǎn)程服務(wù)最終都會(huì)失敗。無論它們多么可靠,這都是不可避免的。這些失敗可能來自多種因素。網(wǎng)絡(luò)問題,硬件問題,暫時(shí)不可用的服務(wù),超出響應(yīng)時(shí)間等。其中一些故障可能已經(jīng)在短時(shí)間內(nèi)自動(dòng)解決,如果再次調(diào)用遠(yuǎn)程服務(wù),它將立即成功響應(yīng)。我們稱這些錯(cuò)誤為暫時(shí)錯(cuò)誤。當(dāng)我們遇到暫時(shí)性錯(cuò)誤時(shí),我們可以做一些事情。
最簡(jiǎn)單的選擇是記錄錯(cuò)誤并放棄。由于重試時(shí)最有可能解決暫時(shí)性錯(cuò)誤,因此您可能會(huì)猜測(cè)這不是最明智的選擇。因此,正確的策略是重試失敗的操作。在沒有明確策略的情況下重試失敗的操作很可能會(huì)給遠(yuǎn)程服務(wù)造成額外的負(fù)擔(dān),因此可能會(huì)使情況變得最糟。
應(yīng)用重試策略之前應(yīng)回答的一些問題是:
客戶將如何確定錯(cuò)誤是否是瞬態(tài)的?
客戶應(yīng)多久重試一次?
客戶端應(yīng)重試多長(zhǎng)時(shí)間?
客戶什么時(shí)候應(yīng)該放棄?
那么,什么時(shí)候重試?
您可以確定這是暫時(shí)性錯(cuò)誤
如果遠(yuǎn)程服務(wù)返回TransientErrorException,那就很好。但是,這并不總是可能的。在這些情況下,我們需要在解釋錯(cuò)誤時(shí)保持機(jī)敏。
客戶端錯(cuò)誤:這些是由客戶端本身引起的錯(cuò)誤。例如格式錯(cuò)誤的請(qǐng)求,導(dǎo)致沖突或執(zhí)行過多的請(qǐng)求。在這種情況下,遠(yuǎn)程服務(wù)將返回4xx錯(cuò)誤。處理客戶端錯(cuò)誤的唯一方法是通過人工干預(yù)來修復(fù)客戶端或請(qǐng)求自身。沒有必要重試這些請(qǐng)求。
服務(wù)器錯(cuò)誤:這些是5xx錯(cuò)誤,表明服務(wù)器端發(fā)生了問題。在這些情況下,重試通常是安全的,因?yàn)槊總€(gè)5xx錯(cuò)誤都不是瞬時(shí)錯(cuò)誤。
網(wǎng)絡(luò)錯(cuò)誤:這些是由于網(wǎng)絡(luò)問題引起的錯(cuò)誤。例如包丟失,路由器/交換機(jī)等硬件問題等。如果可以識(shí)別出這些,可以重試。
服務(wù)是冪等的
冪等意味著,在發(fā)出多個(gè)相同的請(qǐng)求時(shí),其效果與發(fā)出單個(gè)請(qǐng)求的效果相同
根據(jù)HTTP規(guī)范的定義,GET,HEAD,PUT和DELETE是冪等操作。因此,除非遠(yuǎn)程服務(wù)所有者建議,否則可以重試這些請(qǐng)求。另一方面,POST和PATCH不是冪等的,如果不應(yīng)用冪等,則重試是不安全的,因?yàn)樗赡軙?huì)引起副作用,例如多次向客戶收費(fèi)。
重試策略
可以用作重試機(jī)制的幾種策略。選擇正確的策略取決于用例。
操作失敗后,我們可以立即重試。這是我們可以實(shí)施的最簡(jiǎn)單的重試策略。在第一次失敗的重試操作之后,最好放棄或回退更好的策略,因?yàn)檫B續(xù)重試會(huì)給遠(yuǎn)程服務(wù)造成過多的負(fù)載。
操作失敗后,我們可以按固定的時(shí)間間隔重試。該策略為遠(yuǎn)程服務(wù)提供了更多時(shí)間進(jìn)行恢復(fù)。
這兩種策略對(duì)于與用戶進(jìn)行交互的應(yīng)用程序都非常有用,因?yàn)檫@些策略會(huì)重試失敗的操作,如果操作失敗,則很可能會(huì)放棄。因此,用戶不必等待很長(zhǎng)時(shí)間。
如果您的服務(wù)/應(yīng)用程序不直接與用戶交互和/或您有奢望等待更多(例如后臺(tái)操作),則應(yīng)嘗試指數(shù)級(jí)退避。此策略基于后續(xù)重試之間的等待時(shí)間成倍增加。這是一項(xiàng)非常有用的技術(shù),因?yàn)樵诮o定的時(shí)間段內(nèi),它比以前的兩種策略都給遠(yuǎn)程服務(wù)更多的時(shí)間來恢復(fù)并創(chuàng)建更少的負(fù)載。
那么,什么樣的指數(shù)回退策略是什么樣的呢?
這是一種簡(jiǎn)單的指數(shù)退避策略算法的簡(jiǎn)化偽代碼:
通過增加一些抖動(dòng)來分配負(fù)載
最有可能存在多個(gè)客戶端實(shí)例,因此,如果這些客戶端發(fā)出的所有請(qǐng)求都在同一時(shí)間失敗,則我們不希望這些重試重疊。增加抖動(dòng)將使負(fù)載分配更加均勻。使用jiter,我們的算法將是:
通過上述介紹,我們可以知道當(dāng)遠(yuǎn)程服務(wù)暫時(shí)性錯(cuò)誤,并不是所有的錯(cuò)誤都適用重試策略,這也是分情況而定的,更多精彩內(nèi)容,請(qǐng)繼續(xù)關(guān)注中培偉業(yè)。