黨政機(jī)關(guān)如何建設(shè)網(wǎng)站企業(yè)推廣網(wǎng)絡(luò)營銷外包服務(wù)
重試機(jī)制
因為網(wǎng)絡(luò)抖動等原因?qū)е?RPC 調(diào)用失敗,這時候使用重試機(jī)制可以提高請求的最終成功率,減少故障影響,讓系統(tǒng)運行更穩(wěn)定。
重試簡易實現(xiàn)方案
在重試的過程中,為了能夠在約定的時間內(nèi)進(jìn)行安全可靠地重試,在每次觸發(fā)重試之前,我們需要先判定下這個請求是否已經(jīng)超時,如果超時了會直接返回超時異常,否則我們需要重置下這個請求的超時時間,防止因多次重試導(dǎo)致這個請求的處理時間超過用戶配置的超時時間,從而影響到業(yè)務(wù)處理的耗時。在發(fā)起重試、負(fù)載均衡選擇節(jié)點的時候,我們應(yīng)該去掉重試之前出現(xiàn)過問題的那個節(jié)點,這樣可以提高重試的成功率,并且我們允許用戶配置可重試異常的白名單,這樣可以讓 RPC 框架的異常重試功能變得更加友好。
要點
1、確保業(yè)務(wù)是冪等性。防止多次重試導(dǎo)致業(yè)務(wù)
2、超時時間重置,每次重試之前重置超時時間
3、故障機(jī)器剔除,可以參考rocketmq中的故障延遲機(jī)制來剔除故障機(jī)器。通過故障延遲機(jī)制和維護(hù)故障列表faultItemTable來在隨機(jī)選擇的基礎(chǔ)上選性能最優(yōu)和未使用過的可靠Broker來發(fā)送信息,若無則在faultItemTable中選擇次優(yōu)Broker來發(fā)送消息,以此實現(xiàn)高性能,可以有效地規(guī)避故障Borker。
● 若開啟故障延遲機(jī)制則在隨機(jī)遞增取模的基礎(chǔ)上對已發(fā)送過請求的Broker做延遲規(guī)
避,當(dāng)當(dāng)前Broker不在故障機(jī)器表faultItemTable中或存在但當(dāng)前時間超過規(guī)避時限則判定Broker的隊列可用。規(guī)避時限的設(shè)置是通過兩個數(shù)組latencyMax和notAvailableDuration維護(hù)的,當(dāng)上次請求耗時時間latency超過latencyMax中的某個值,則會在數(shù)組notAvailableDuration中選擇對應(yīng)的時間期限值進(jìn)行規(guī)避,因此當(dāng)前請求時間-(上次請求時間+規(guī)避時限)>0則判定可用。
private long[] latencyMax = {50L, 100L, 550L, 1000L, 2000L, 3000L, 15000L};
private long[] notAvailableDuration = {0L, 0L, 30000L, 60000L, 120000L, 180000L, 600000L};
● 多次輪訓(xùn)選擇一個隊列判斷是否可用,若有可用隊列則直接返回可用隊列。若無可用隊列則從故障Broker列表中隨機(jī)選擇一個Broker,若該Broker中有寫隊列,則將該Broker和寫隊列信息寫入消息隊列MessageQueue中并返回。若無,則從故障列表中剔除該結(jié)點(真正從路由信息中剔除),并隨機(jī)從messageQueueList中選擇一個隊列來發(fā)送消息。
重試危害
重試有放大故障的風(fēng)險。無限制的重試可以打高下游應(yīng)用的負(fù)載,導(dǎo)致其宕機(jī)無法提供正常服務(wù)。而且重試還會存在鏈路放大的效應(yīng)。假設(shè)正常訪問量是 n,鏈路一共有 m 層,每層重試次數(shù)為 r,則最后一層受到的訪問量最大,為 n * r ^ (m - 1) 。這種指數(shù)放大的效應(yīng)很可怕,可能導(dǎo)致鏈路上多層都被打掛,整個系統(tǒng)雪崩。
退避策略
對于一些暫時性的錯誤,如網(wǎng)絡(luò)抖動等,可能立即重試還是會失敗,通常等待一小會兒再重試的話成功率會較高,并且也可能打散上游重試的時間,較少因為同時都重試而導(dǎo)致的下游瞬間流量高峰。決定等待多久之后再重試的方法叫做退避策略,我們實現(xiàn)了常見的退避策略,如:
線性退避:每次等待固定時間后重試。
隨機(jī)退避:在一定范圍內(nèi)隨機(jī)等待一個時間后重試。
指數(shù)退避:連續(xù)重試時,每次等待時間都是前一次的倍數(shù)。
重試機(jī)制控制方案
1、單點重試限制:滑動時間窗口方式,對于同一個資源請求,通過計算時間窗口內(nèi)的成功率來限制上游是否允許重試。
2、限制鏈路重試:1)響應(yīng)包中設(shè)置retry_flag來通知上游是否可以進(jìn)行重試。2)返回業(yè)務(wù)碼告知上游是否可以進(jìn)行重試(入侵性強(qiáng))
參考:https://www.infoq.cn/article/5fboevkal0gvgvgeac4z
https://time.geekbang.org/column/article/211261