Dubbo集群容错
轉(zhuǎn)自dubbo官網(wǎng)文檔http://dubbo.apache.org/zh-cn/blog/dubbo-cluster-error-handling.html
Design For failure
在分布式系統(tǒng)中,集群某個某些節(jié)點(diǎn)出現(xiàn)問題是大概率事件,因此在設(shè)計(jì)分布式RPC框架的過程中,必須要把失敗作為設(shè)計(jì)的一等公民來對待。一次調(diào)用失敗之后,應(yīng)該如何選擇對失敗的選擇策略,這是一個見仁見智的問題,每種策略可能都有自己獨(dú)特的應(yīng)用場景。因此,作為框架來說,應(yīng)當(dāng)針對不同場景提供多種策略,供用戶進(jìn)行選擇。
在Dubbo設(shè)計(jì)中,通過Cluster這個接口的抽象,把一組可供調(diào)用的Provider信息組合成為一個統(tǒng)一的Invoker供調(diào)用方進(jìn)行調(diào)用。經(jīng)過路由規(guī)則過濾,負(fù)載均衡選址后,選中一個具體地址進(jìn)行調(diào)用,如果調(diào)用失敗,則會按照集群配置的容錯策略進(jìn)行容錯處理。
Dubbo默認(rèn)內(nèi)置了若干容錯策略,如果不能滿足用戶需求,則可以通過自定義容錯策略進(jìn)行配置。
內(nèi)置容錯策略
Dubbo主要內(nèi)置了如下幾種策略:
- Failover(失敗自動切換)
- Failsafe(失敗安全)
- Failfast(快速失敗)
- Failback(失敗自動恢復(fù))
- Forking(并行調(diào)用)
- Broadcast(廣播調(diào)用)
這些名稱比較相似,概念也比較容易混淆,下面逐一進(jìn)行解釋。
Failover(失敗自動切換)
Failover是高可用系統(tǒng)中的一個常用概念,服務(wù)器通常擁有主備兩套機(jī)器配置,如果主服務(wù)器出現(xiàn)故障,則自動切換到備服務(wù)器中,從而保證了整體的高可用性。
Dubbo也借鑒了這個思想,并且把它作為Dubbo默認(rèn)的容錯策略。當(dāng)調(diào)用出現(xiàn)失敗的時候,根據(jù)配置的重試次數(shù),會自動從其他可用地址中重新選擇一個可用的地址進(jìn)行調(diào)用,直到調(diào)用成功,或者是達(dá)到重試的上限位置。
Dubbo里默認(rèn)配置的重試次數(shù)是2,也就是說,算上第一次調(diào)用,最多會調(diào)用3次。
其配置方法,容錯策略既可以在服務(wù)提供方配置,也可以服務(wù)調(diào)用方進(jìn)行配置。而重試次數(shù)的配置則更為靈活,既可以在服務(wù)級別進(jìn)行配置,也可以在方法級別進(jìn)行配置。具體優(yōu)先順序?yàn)?#xff1a;
服務(wù)調(diào)用方方法級配置 > 服務(wù)調(diào)用方服務(wù)級配置 > 服務(wù)提供方方法級配置 > 服務(wù)提供方服務(wù)級配置以XML方式為例,具體配置方法如下:
服務(wù)提供方,服務(wù)級配置
<dubbo:service interface="org.apache.dubbo.demo.DemoService" ref="demoService" cluster="failover" retries="2" />服務(wù)提供方,方法級配置
<dubbo:service interface="org.apache.dubbo.demo.DemoService" ref="demoService"cluster="failover"> <dubbo:method name="sayHello" retries="2" /> </dubbo:reference>服務(wù)調(diào)用方,服務(wù)級配置
<dubbo:reference id="demoService" interface="org.apache.dubbo.demo.DemoService" cluster="failover" retries="1"/>服務(wù)調(diào)用方,方法級配置:
<dubbo:reference id="demoService" interface="org.apache.dubbo.demo.DemoService" cluster="failover"> <dubbo:method name="sayHello" retries="3" /> </dubbo:reference>Failover可以自動對失敗進(jìn)行重試,對調(diào)用者屏蔽了失敗的細(xì)節(jié),但是Failover策略也會帶來一些副作用:
- 重試會額外增加一下開銷,例如增加資源的使用,在高負(fù)載系統(tǒng)下,額外的重試可能讓系統(tǒng)雪上加霜。
- 重試會增加調(diào)用的響應(yīng)時間。
- 某些情況下,重試甚至?xí)斐少Y源的浪費(fèi)。考慮一個調(diào)用場景,A->B->C,如果A處設(shè)置了超時100ms,再B->C的第一次調(diào)用完成時已經(jīng)超過了100ms,但很不幸B->C失敗,這時候會進(jìn)行重試,但其實(shí)這時候重試已經(jīng)沒有意義,因此在A看來這次調(diào)用已經(jīng)超時,A可能已經(jīng)開始執(zhí)行其他邏輯。
Failsafe(失敗安全)
失敗安全策略的核心是即使失敗了也不會影響整個調(diào)用流程。通常情況下用于旁路系統(tǒng)或流程中,它的失敗不影響核心業(yè)務(wù)的正確性。在實(shí)現(xiàn)上,當(dāng)出現(xiàn)調(diào)用失敗時,會忽略此錯誤,并記錄一條日志,同時返回一個空結(jié)果,在上游看來調(diào)用是成功的。
應(yīng)用場景,可以用于寫入審計(jì)日志等操作。
?
Failfast(快速失敗)
某些業(yè)務(wù)場景中,某些操作可能是非冪等的,如果重復(fù)發(fā)起調(diào)用,可能會導(dǎo)致出現(xiàn)臟數(shù)據(jù)等。例如調(diào)用某個服務(wù),其中包含一個數(shù)據(jù)庫的寫操作,如果寫操作完成,但是在發(fā)送結(jié)果給調(diào)用方的過程中出錯了,那么在調(diào)用發(fā)看來這次調(diào)用失敗了,但其實(shí)數(shù)據(jù)寫入已經(jīng)完成。這種情況下,重試可能并不是一個好策略,這時候就需要使用到Failfast策略,調(diào)用失敗立即報(bào)錯。讓調(diào)用方來決定下一步的操作并保證業(yè)務(wù)的冪等性。
?
Failback(失敗自動恢復(fù))
Failback通常和Failover兩個概念聯(lián)系在一起。在高可用系統(tǒng)中,當(dāng)主機(jī)發(fā)生故障,通過Failover進(jìn)行主備切換后,待故障恢復(fù)后,系統(tǒng)應(yīng)該具備自動恢復(fù)原始配置的能力。
Dubbo中的Failback策略中,如果調(diào)用失敗,則此次失敗相當(dāng)于Failsafe,將返回一個空結(jié)果。而與Failsafe不同的是,Failback策略會將這次調(diào)用加入內(nèi)存中的失敗列表中,對于這個列表中的失敗調(diào)用,會在另一個線程中進(jìn)行異步重試,重試如果再發(fā)生失敗,則會忽略,即使重試調(diào)用成功,原來的調(diào)用方也感知不到了。因此它通常適合于,對于實(shí)時性要求不高,且不需要返回值的一些異步操作。
?
按照目前的實(shí)現(xiàn),Failback策略還有一些局限,例如內(nèi)存中的失敗調(diào)用列表沒有上限,可能導(dǎo)致堆積,異步重試的執(zhí)行間隔無法調(diào)整,默認(rèn)是5秒。
Forking(并行調(diào)用)
上述幾種策略中,主要都是針對調(diào)用失敗發(fā)生后如何進(jìn)行彌補(bǔ)的角度去考慮的,而Forking策略則跟上述幾種策略不同,是一種典型的用成本換時間的思路。即第一次調(diào)用的時候就同時發(fā)起多個調(diào)用,只要其中一個調(diào)用成功,就認(rèn)為成功。在資源充足,且對于失敗的容忍度較低的場景下,可以采用此策略。
?
Broadcast(廣播調(diào)用)
在某些場景下,可能需要對服務(wù)的所有提供者進(jìn)行操作,此時可以使用廣播調(diào)用策略。此策略會逐個調(diào)用所有提供者,只要任意有一個提供者出錯,則認(rèn)為此次調(diào)用出錯。通常用于通知所有提供者更新緩存或日志等本地資源信息。
?
各種策略對比
下表對各種策略做一個簡單對比,
| Failover | 對調(diào)用者屏蔽調(diào)用失敗的信息 | 增加RT,額外資源開銷,資源浪費(fèi) | 對調(diào)用rt不敏感的場景 |
| Failfast | 業(yè)務(wù)快速感知失敗狀態(tài)進(jìn)行自主決策 | 產(chǎn)生較多報(bào)錯的信息 | 非冪等性操作,需要快速感知失敗的場景 |
| Failsafe | 即使失敗了也不會影響核心流程 | 對于失敗的信息不敏感,需要額外的監(jiān)控 | 旁路系統(tǒng),失敗不影響核心流程正確性的場景 |
| Failback | 失敗自動異步重試 | 重試任務(wù)可能堆積 | 對于實(shí)時性要求不高,且不需要返回值的一些異步操作 |
| Forking | 并行發(fā)起多個調(diào)用,降低失敗概率 | 消耗額外的機(jī)器資源,需要確保操作冪等性 | 資源充足,且對于失敗的容忍度較低,實(shí)時性要求高的場景 |
| Broadcast | 支持對所有的服務(wù)提供者進(jìn)行操作 | 資源消耗很大 | 通知所有提供者更新緩存或日志等本地資源信息 |
自定義容錯策略
如果上述內(nèi)置的容錯策略無法滿足你的需求,還可以通過擴(kuò)展的方式來實(shí)現(xiàn)自定義容錯策略。
擴(kuò)展接口
com.alibaba.dubbo.rpc.cluster.Cluster
擴(kuò)展配置
<dubbo:service cluster="xxx" />擴(kuò)展示例
下面通過一個例子來展示如何使用自定義的容錯策略。 Maven 項(xiàng)目結(jié)構(gòu):
src|-main|-java|-com|-xxx|-XxxCluster.java (實(shí)現(xiàn)Cluster接口)|-resources|-META-INF|-dubbo|-org.apache.dubbo.rpc.cluster.Cluster (純文本文件,內(nèi)容為:xxx=com.xxx.XxxCluster)XxxCluster.java:
package com.xxx;import org.apache.dubbo.rpc.cluster.Cluster; import org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker; import org.apache.dubbo.rpc.cluster.Directory; import org.apache.dubbo.rpc.cluster.LoadBalance; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcException; import java.util.List; public class XxxCluster implements Cluster {META-INF/dubbo/com.alibaba.dubbo.rpc.cluster.Cluster文件的內(nèi)容為
xxx=com.xxx.XxxCluster轉(zhuǎn)載于:https://www.cnblogs.com/twoheads/p/10131929.html
總結(jié)
- 上一篇: oracle执行计划的rows不对,Or
- 下一篇: 可曾听闻【大话】二字