Dubbo的總體架構(gòu)
一、Duboo基本概念解釋
Dubbo是一種分布式服務(wù)框架释簿。除了可以提供服務(wù)之外亚隅,還可以實現(xiàn)軟負載均衡。它還提供了兩個功能Monitor監(jiān)控中心和調(diào)用中心庶溶。這兩個是可選的煮纵,需要單獨配置。
Dubbo的計數(shù)架構(gòu)圖如下:
我們解釋以下這個架構(gòu)圖:
Consumer服務(wù)消費者偏螺,Provider服務(wù)提供者行疏。Container服務(wù)容器。消費當然是invoke提供者了套像,invoke這條實線按照圖上的說明當然同步的意思了酿联,多說一句,在實際調(diào)用過程中夺巩,Provider的位置對于Consumer來說是透明的贞让,上一次調(diào)用服務(wù)的位置(IP地址)和下一次調(diào)用服務(wù)的位置,是不確定的柳譬。這個地方就是實現(xiàn)了軟負載喳张。
服務(wù)提供者先啟動start,然后注冊register服務(wù)美澳。
消費訂閱subscribe服務(wù)销部,如果沒有訂閱到自己想獲得的服務(wù),它會不斷的嘗試訂閱制跟。新的服務(wù)注冊到注冊中心以后舅桩,注冊中心會將這些服務(wù)通過notify到消費者。
Monitor這是一個監(jiān)控雨膨,圖中虛線表明Consumer和Provider通過異步的方式發(fā)送消息至Monitor擂涛,Consumer和Provider會將信息存放在本地磁盤,平均1min會發(fā)送一次信息哥放。Monitor在整個架構(gòu)中是可選的(圖中的虛線并不是可選的意思)歼指,Monitor功能需要單獨配置,不配置或者配置以后甥雕,Monitor掛掉并不會影響服務(wù)的調(diào)用踩身。
二、dubbo原理
本篇博客的內(nèi)容總體上比較抽象社露,如果一個想馬上使用dubbo的同學(xué)來說挟阻,讀這篇博客效果不太好,本篇博客沒有寫怎么使用峭弟、配置dubbo附鸽,接下來,我再令寫一篇dubbo入門包含demo的博客瞒瘸。
I坷备、初始化過程細節(jié):上圖中的第一步start,就是將服務(wù)裝載容器中情臭,然后準備注冊服務(wù)省撑。和spring中啟動過程類似,spring啟動時俯在,將bean裝載進容器中的時候竟秫,首先要解析bean。所以dubbo也是先讀配置文件解析服務(wù)跷乐。
解析服務(wù):
1)肥败、基于dubbo.jar內(nèi)的Meta-inf/spring.handlers配置,spring在遇到dubbo名稱空間時愕提,會回調(diào)DubboNamespaceHandler類馒稍。
2)、所有的dubbo標簽揪荣,都統(tǒng)一用DubboBeanDefinitionParser進行解析筷黔,基于一對一屬性映射,將XML標簽解析為Bean對象仗颈。源碼截圖:在ServiceConfig.export或者ReferenceConfig.get初始化時佛舱,將Bean對象轉(zhuǎn)會為url格式,將所以Bean屬性轉(zhuǎn)成url的參數(shù)挨决。然后將URL傳給Protocol擴展點请祖,基于擴展點的Adaptive機制,根據(jù)URL的協(xié)議頭脖祈,進行不同協(xié)議的服務(wù)暴露和引用肆捕。
暴露服務(wù):
a、只暴露服務(wù)端口
在沒有使用注冊中心的情況盖高,這種情況一般適用在開發(fā)環(huán)境下慎陵,服務(wù)的調(diào)用這和提供在同一個IP上眼虱,只需要打開服務(wù)的端口即可。即席纽,當配置orServiceConfig解析出的URL的格式為:Dubbo://service-host/com.xxx.TxxService?version=1.0.0基于擴展點的Adaptiver機制捏悬,通過URL的“dubbo://”協(xié)議頭識別,直接調(diào)用DubboProtocol的export方法润梯,打開服務(wù)端口过牙。
b、向注冊中心暴露服務(wù):
和上一種的區(qū)別:需要將服務(wù)的IP和端口一同暴露給注冊中心纺铭。ServiceConfig解析出的url格式為:registry://registry-host/com.alibaba.dubbo.registry.RegistryService?export=URL.encode(“dubbo://service-host/com.xxx.TxxService?version=1.0.0”)
基于擴展點的Adaptive機制寇钉,通過URL的“registry://”協(xié)議頭識別,調(diào)用RegistryProtocol的export方法舶赔,將export參數(shù)中的提供者URL先注冊到注冊中心扫倡,再重新傳給Protocol擴展點進行暴露:Dubbo://service-host/com.xxx.TxxService?version=1.0.0
引用服務(wù):
a、直接引用服務(wù):
在沒有注冊中心的竟纳,直連提供者情況下镊辕,ReferenceConfig解析出的URL格式為:Dubbo://service-host/com.xxx.TxxService?version=1.0.0
基于擴展點的Adaptive機制,通過url的“dubbo://”協(xié)議頭識別蚁袭,直接調(diào)用DubboProtocol的refer方法征懈,返回提供者引用。
b揩悄、從注冊中心發(fā)現(xiàn)引用服務(wù):
此時卖哎,ReferenceConfig解析出的URL的格式為:·registry://registry-host/com.alibaba.dubbo.registry.RegistryService?refer=URL.encode(“consumer://consumer-host/com.foo.FooService?version=1.0.0”)
基于擴展點的Apaptive機制,通過URL的“registry://”協(xié)議頭識別删性,就會調(diào)用RegistryProtocol的refer方法亏娜,基于refer參數(shù)總的條件,查詢提供者URL蹬挺,如:Dubbo://service-host/com.xxx.TxxService?version=1.0.0
基于擴展點的Adaptive機制维贺,通過提供者URL的“dubbo://”協(xié)議頭識別,就會調(diào)用DubboProtocol的refer方法巴帮,得到提供者引用溯泣。然后RegistryProtocol將多個提供者引用,通過Cluster擴展點榕茧,偽裝成單個提供這引用返回垃沦。
三、遠程調(diào)用細節(jié)
服務(wù)提供者暴露一個服務(wù)的詳細過程:
上圖是服務(wù)提供者暴露服務(wù)的主過程:首先ServiceConfig類拿到對外提供服務(wù)的實際類ref用押,然后將ProxyFactory類的getInvoker方法使用ref生成一個AbstractProxyInvoker實例肢簿,到這一步就完成具體服務(wù)到invoker的轉(zhuǎn)化。接下來就是Invoker轉(zhuǎn)換到Exporter的過程。
Dubbo處理服務(wù)暴露的關(guān)鍵就在Invoker轉(zhuǎn)換到Exporter的過程池充,下面我們以Dubbo和rmi這兩種典型協(xié)議的實現(xiàn)來進行說明:
Dubbo的實現(xiàn):Dubbo協(xié)議的Invoker轉(zhuǎn)為Exporter發(fā)生在DubboProtocol類的export方法桩引,它主要是打開socket偵聽服務(wù),并接收客戶端發(fā)來的各種請求收夸,通訊細節(jié)由dubbo自己實現(xiàn)阐污。
Rmi的實現(xiàn):RMI協(xié)議的Invoker轉(zhuǎn)為Exporter發(fā)生在RmiProtocol類的export方法,他通過Spring或Dubbo或JDK來實現(xiàn)服務(wù)咱圆,通訊細節(jié)由JDK底層來實現(xiàn)。
服務(wù)提供者暴露一個服務(wù)的詳細過程
上圖是服務(wù)消費的主過程:首先ReferenceConfig類的init方法調(diào)用Protocol的refer方法生成Invoker實例功氨。接下來把Invoker轉(zhuǎn)為客戶端需要的接口