Dubbo :是一個RPC框架,SOA框架:
Dubbo缺省協議采用單一長連接和NIO異步通訊,適合於小數據量大並發的服務調用,以及服務消費者機器數遠大於服務提供者機器數的情況。
作為RPC:支持各種傳輸協議,如dubbo,hession,json,fastjson,底層采用mina,netty長連接進行傳輸!典型的provider和cusomer模式!
作為SOA:具有服務治理功能,提供服務的注冊和發現!用zookeeper實現注冊中心!啟動時候服務端會把所有接口注冊到注冊中心,並且訂閱configurators,服務消費端訂閱provide,configurators,routers,訂閱變更時,zk會推送providers,configuators,routers,啟動時注冊長連接,進行通訊!proveider和provider啟動后,后台啟動定時器,發送統計數據到monitor(監控中心)!提供各種容錯機制和負載均衡策略!!
我們解釋以下這個架構圖:https://yq.aliyun.com/articles/38380
Consumer服務消費者,Provider服務提供者。Container服務容器。消費當然是invoke提供者了,invoke這條實線按照圖上的說明當然同步的意思了,多說一句,在實際調用過程中,Provider的位置對於Consumer來說是透明的,上一次調用服務的位置(IP地址)和下一次調用服務的位置,是不確定的。這個地方就是實現了軟負載。
服務提供者先啟動start,然后注冊register服務。
消費訂閱subscribe服務,如果沒有訂閱到自己想獲得的服務,它會不斷的嘗試訂閱。新的服務注冊到注冊中心以后,注冊中心會將這些服務通過notify到消費者。
Monitor這是一個監控,圖中虛線表明Consumer 和Provider通過異步的方式發送消息至Monitor,Consumer和Provider會將信息存放在本地磁盤,平均1min會發送一次信息。Monitor在整個架構中是可選的(圖中的虛線並不是可選的意思),Monitor功能需要單獨配置,不配置或者配置以后,Monitor掛掉並不會影響服務的調用。
netty 是什么?
“netty 是一個基於nio的客戶、服務器端編程框架,netty提供異步的,事件驅動的網絡應用程序框架和工具,可以快速開發高可用的客戶端和服務器。
netty是基於nio的,它封裝了jdk的nio,讓我們使用起來更加方法靈活。
二、dubbo原理?
I、初始化過程細節:
上圖中的第一步start,就是將服務裝載容器中,然后准備注冊服務。和Spring中啟動過程類似,spring啟動時,將bean裝載進容器中的時候,首先要解析bean。所以dubbo也是先讀配置文件解析服務。
解析服務:
1)、基於dubbo.jar內的Meta-inf/spring.handlers配置,spring在遇到dubbo名稱空間時,會回調DubboNamespaceHandler類。
2)、所有的dubbo標簽,都統一用DubboBeanDefinitionParser進行解析,基於一對一屬性映射,將XML標簽解析為Bean對象。
在ServiceConfig.export 或者ReferenceConfig.get 初始化時,將Bean對象轉會為url格式,將所以Bean屬性轉成url的參數。
然后將URL傳給Protocol擴展點,基於擴展點的Adaptive機制,根據URL的協議頭,進行不同協議的服務暴露和引用。
a、 只暴露服務端口
在沒有使用注冊中心的情況,這種情況一般適用在開發環境下,服務的調用這和提供在同一個IP上,只需要打開服務的端口即可。
即,當配置 or
ServiceConfig解析出的URL的格式為:
Dubbo://service-host/com.xxx.TxxService?version=1.0.0
基於擴展點的Adaptiver機制,通過URL的“dubbo://”協議頭識別,直接調用DubboProtocol的export()方法,打開服務端口。
b、向注冊中心暴露服務:
和上一種的區別:需要將服務的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://”協議頭識別,調用RegistryProtocol的export方法,將export參數中的提供者URL先注冊到注冊中心,再重新傳給Protocol擴展點進行暴露: Dubbo://service-host/com.xxx.TxxService?version=1.0.0
四、服務暴露和消費的詳細過程
(1)服務提供者暴露一個服務的詳細過程
服務提供者暴露服務的主過程:
首先ServiceConfig類拿到對外提供服務的實際類ref(如:HelloWorldImpl),然后通過ProxyFactory類的getInvoker方法使用ref生成一個AbstractProxyInvoker實例,
到這一步就完成具體服務到Invoker的轉化。接下來就是Invoker轉換到Exporter的過程。
Dubbo處理服務暴露的關鍵就在Invoker轉換到Exporter的過程(如上圖中的紅色部分),下面我們以Dubbo和RMI這兩種典型協議的實現來進行說明:
Dubbo的實現:
Dubbo協議的Invoker轉為Exporter發生在DubboProtocol類的export方法,它主要是打開socket偵聽服務,並接收客戶端發來的各種請求,通訊細節由Dubbo自己實現。
RMI的實現:
RMI協議的Invoker轉為Exporter發生在RmiProtocol類的export方法,
它通過Spring或Dubbo或JDK來實現RMI服務,通訊細節這一塊由JDK底層來實現,這就省了不少工作量。
(2)服務消費者消費一個服務的詳細過程
服務消費的主過程:
首先ReferenceConfig類的init方法調用Protocol的refer方法生成Invoker實例(如上圖中的紅色部分),這是服務消費的關鍵。
接下來把Invoker轉換為客戶端需要的接口(如:HelloWorld)。