通過代理對象進行遠程方法的調用,從大的方面也可以分為三步,分別是代理調用、容錯負載和遠程通信。
容錯負載是Dubbo的重要組成模塊,該模塊實現(xiàn)了多種集群特性,還實現(xiàn)了目錄服務、負載均衡、路由策略和服務治理配置等特性。
Invoker是服務提供者(Provider)的抽象,Invoker封裝了Provider地址及服務接口信息。
Directory代表多個Invoker,可以把它看作List,但與List不同的是,它的值可能是動態(tài)變化的,比如注冊中心推送變更。
Cluster將Directory中的多個Invoker偽裝成一個Invoker,偽裝過程包含了容錯邏輯,調用失敗后,重試另一個。
Router可以從多個Invoker中通過路由規(guī)則進行過濾和篩選。
LoadBalance可以從多個Invoker中選出一個使用。
RoundRobinLoadBalance:權重輪詢算法,按照公約后的權重設置輪詢比例
原理:把來自用戶的請求輪流分配給內部中的服務器。例如:從1開始,一直到N(其中,N是內部服務器的總數(shù)),然后重新開始循環(huán)。
LeastActiveLoadBalance:最少活躍調用數(shù)均衡算法
原理:最少活躍調用數(shù),活躍數(shù)指調用前后計數(shù)差,使慢的機器收到更少。
ConsistentHashLoadBalance:一致性Hash算法
原理:一致性Hash,相同參數(shù)的請求總是發(fā)到同一個提供者。一致性Hash算法可以解決服務提供者的增加、移除及“掛掉”時的情況,也可以通過構建虛擬節(jié)點,盡可能避免分配失衡,具有很好的平衡性。
RandomLoadBalance:隨機均衡算法(Dubbo的默認負載均衡策略)
原理:按權重設置隨機概率,如果每個提供者的權重都相同,那么根據(jù)列表長度直接隨機選取一個,如果權重不同,則累加權重值。從0~累加的權重值中選取一個隨機數(shù),然后判斷該隨機數(shù)落在哪個提供者上。
FailoverCluster:失敗轉移
當出現(xiàn)失敗時,重試其他服務器,通常用于讀操作,但重試會帶來更長延遲(默認集群策略)。
FailfastCluster:快速失敗
只發(fā)起一次調用,失敗立即報錯,通常用于非冪等性操作。
FailbackCluster:失敗自動恢復
對于Invoker調用失敗,后臺記錄失敗請求,任務定時重發(fā),通常用于通知。
BroadcastCluster:廣播調用
遍歷所有Invokers,如果調用其中某個invoker報錯,則“catch”住異常,這樣就不影響其他Invoker調用。
AvailableCluster:獲取可用的調用
遍歷所有Invokers并判斷Invoker.isAvalible,只要有一個為true就直接調用返回,不管成不成功。
FailsafeCluster:失敗安全
出現(xiàn)異常時,直接忽略,通常用于寫入審計日志等操作。
ForkingCluster:并行調用
只要一個成功即返回,通常用于實時性要求較高的操作,但需要浪費更多的服務資源。
MergeableCluster:分組聚合
按組合并返回結果,比如某個服務接口有多種實現(xiàn),可以用group區(qū)分,調用者調用多種實現(xiàn)并將得到的結果合并。
Directory:代表多個Invoker,可以看作List,它的值可能是動態(tài)變化的,比如注冊中心推送變更。
StaticDirectory:靜態(tài)目錄服務,它的所有Invoker通過構造函數(shù)傳入,并且將所有Invoker返回。
RegistryDirectory:注冊目錄服務,它的Invoker集合是從注冊中心獲取的,并且實現(xiàn)了NotifyListener接口的notify(List)方法。
AbstractDirectory:所有目錄服務實現(xiàn)的抽象類,它在獲取所有的Invoker后,通過Router服務進行路由過濾。
ConditionRouter:基于條件表達式的路由規(guī)則,不足之處是在規(guī)則復雜且多分支的情況下,規(guī)則不容易描述。
ScriptRouter:基于腳本引擎的路由規(guī)則,沒有運行沙箱,腳本能力強大,可能成為后門。
那么在選擇出一個可用服務后,接下來就正式進入服務調用環(huán)節(jié)了,也就是Result result = invoker.invoke(invocation)。這一行代碼會經(jīng)過一系列的Filter通過配置好的通信協(xié)議,遠程調用相應的Provider,執(zhí)行并返回結果,返回結果和異常信息全部封裝到Result對象中,最終實現(xiàn)一次完整的調用過程。