前言
本來是想把整個dubbo原始碼解析一次性弄完,再做成一個系列來發布的,但是正巧最近有位好朋友要去杭州面試,就和我交流了一下.本著對dubbo原始碼略有心得的心態,在交流過程中也發表了個人的一些粗劣的拙見.但是非常不幸的是,交流過程中我這位朋友問到了幾個問題,我卻沒能回答得上,讓我感到十分慚愧.故而將原計劃提前,並且定期整理,做到定期更新一篇dubbo原始碼解析.好讓自己的知識盲點儘早暴露出來.本篇講的就是dubbo的一個重要概念,叢集容錯
.既然你已經在看原始碼解析了,那麼我就假設你對dubbo的使用上有一定的經驗,並且看過了dubbo的官網的對叢集容錯的簡單介紹
之前有寫過原始碼解析的一些拙見,例如別怕,手把手帶你撕、拉、扯下SpringMVC的外衣, 別怕看原始碼,一張圖搞定Mybatis的Mapper原理,但是經過一些思考還是有比較多的缺陷,這主要表現在太猴急,導致前戲不足,上來就直接進入原始碼,沒有鋪墊概念.大多數人看原始碼主要存在的問題是,層級結構深,導致進了兩三個方法之後,根本不知道自己在哪,久而久之,對看原始碼產生了恐懼
所以本篇嘗試改變之前的風格,總結起來就是先總體,後區域性.也就是先把需要注意的概念先丟擲來,把整體架構圖先畫出來.讓讀者拿著”地圖”跟著我的腳步,並且每一步我都提醒,現在我們在哪,我們下一步要做什麼,這樣才不會迷失方向.
前期鋪墊
這張是官網的對於叢集容錯的架構設計圖,即使你有一定的使用經驗,第一眼看到這個圖可能還是有些懵逼.因為這個圖是從設計的角度畫出來的,而不是使用的角度.但是即使這個圖你看不懂也不影響你對本文的閱讀,但是你必須要記住三個關鍵詞,因為這三個關鍵詞接下來會貫穿全文,他們就是Directory
,Router
,LoadBalance
再接下來給大家一張”地圖”,”地圖”上我已經標記了序號,再下面的原始碼分析中,我也會實時提醒我們所在的位置,以至於不會迷失方向.
環境準備
既然是叢集,那麼首先要啟動兩個Provider
,我這裡是一個虛擬機器,一個本地的方式,因為環境準備不是本文重點,因此略過.本文所用到的原始碼是2.5.4
版本,可以在guihub
上找到.
正式發車
這次示例選用的原始碼用dubbo-demo
的dubbo-demo-consumer
,如果對dubbo原理有些簡單的瞭解就知道,他給介面注入的不是介面的實現類,而是一個代理類,如下圖
接著自然是到了代理類的invoke方法裡,從圖中我們也可以看出,他用的是jdk的動態代理
下面要開始緊盯著地圖了,他現在就要開始執行地圖中的序號1,此時我們抵達MockClusterInvoker
這個類
執行invoke
就要開始進入到叢集,也就是Cluster
,現在第一個關鍵詞Directory
已經浮出水面了
現在到了AbstractDirectory
,也就是序號3
這個methodInvokerMap
也比較重要,後面的文章會講一下這個,但是我們這部分程式碼就可以從出,他是要從methodInvokerMap
中取出invokers
如圖所示
將invokers返回後(序號5),下面來到了第二個關鍵詞,Router
,開始進入路由,現在我們到了序號6,此時到了MockInvokersSelector
類,不要看類名和Router
沒有關係,其實他是Router
介面的實現類,從官網的介紹圖中我們也可以看到Router
分為Script
和Condition
兩種,翻譯過來也就是指令碼路由
和條件路由
這個後面再詳細介紹,本篇主要介紹整體架構
原始碼的命名是很規範的,從getNormalInvokers
就可以得知,他是要拿到能正常執行的invokers
,並將其返回.也就是序號7
這個時候我們再次回到了AbstractClusterInvoker
這個類,我們先不急著往下走,先適時做個總結.因為三個關鍵詞,現在都已經出現了兩個,那這個時候要回憶一下上面這些步驟,做一個總結.上面出現的這兩個關鍵詞,其實無非就是做兩件事
- 在
Directory
中找出本次叢集中的全部invokers
- 在
Router
中,將上一步的全部invokers
挑選出能正常執行的invokers
對應到”地圖”,也就是序號5和序號7.(再次提醒,一定要緊跟地圖的序號,不然很容易迷失方向)
從上面步驟我們也知道,已經挑選出能正常執行的invokers
了,但是假如2個做叢集,但是這兩個都是正常的,我到底要執行哪一個呢?帶著這個問題,我們繼續往下看
根據官網的描述
在叢集呼叫失敗時,Dubbo 提供了多種容錯方案,預設為 failover 重試。
所以這個時候是到了FailoverClusterInvoker
類,但是如果你配置的是Failover Cluster(快速失敗)
,Failsafe Cluster(失敗安全)
,Failback Cluster(失敗自動恢復)
,Forking Cluster(並行呼叫多個伺服器,只要一個成功即返回)
,Broadcast Cluster(廣播呼叫所有提供者,逐個呼叫,任意一臺報錯則報錯)
他也會到達相應的類
下面就要開始第三個關鍵詞浮出水面,也就是LoadBalance(負載均衡)
,此時的位置是序號11
根據前面我們知道,現在已經有兩個備選的invokers
,但是究竟哪一個能執行,這個需要LoadBalance
來決定.這裡涉及到了一定的演算法,後面我也會有一篇文章加以介紹.劇透一下,這個在2.5.4
的版本中,這個演算法還是存在一些小的bug,此時我們的位置是序號13
到達終點站.我們回憶總結一下,文初提到的三個關鍵詞,在這個叢集容錯的整體架構過程中,dubbo究竟做了什麼.其實也就是三件事
- 在
Directory
中找出本次叢集中的全部invokers
- 在
Router
中,將上一步的全部invokers
挑選出能正常執行的invokers
- 在
LoadBalance
中,將上一步的能正常的執行invokers
中,根據配置的負載均衡策略,挑選出需要執行的invoker
寫在末尾
本文也到達尾聲,後面還會不定期更新dubbo的原始碼解析(包括dubbo核心,服務釋出和訂閱,叢集容錯,編碼和解碼),鑑於本文是整體架構解析,後面還會對這文中提到的三個關鍵字做詳細的解析.鑑於本人才疏學淺,不對的地方還望斧正,也歡迎關注我的簡書,名稱為肥朝