一、前言
工欲善其事,必先利其器,前面通過(guò)幾篇文章簡(jiǎn)單的介紹了如何使用Dubbo搭建一個(gè)簡(jiǎn)單的分布式系統(tǒng),在接下來(lái)的的一段時(shí)間就來(lái)研究Dubbo原理設(shè)計(jì)卧斟,本文作為原理設(shè)計(jì)的開篇先整體介紹下dubbo的架構(gòu)殴边。
二、整體架構(gòu)
dubbo官方的這個(gè)圖很復(fù)雜珍语,但是一開始沒有必要深入細(xì)節(jié)锤岸,下面我們簡(jiǎn)單講解主要模塊。
其中Service 和 Config 層為 API板乙,對(duì)應(yīng)服務(wù)提供方來(lái)說(shuō)是使用ServiceConfig來(lái)代表一個(gè)要發(fā)布的服務(wù)配置對(duì)象是偷,對(duì)應(yīng)服務(wù)消費(fèi)方來(lái)說(shuō)ReferenceConfig代表了一個(gè)要消費(fèi)的服務(wù)的配置對(duì)象∧汲眩可以直接初始化配置類蛋铆,也可以通過(guò) spring 解析配置生成配置類。
其它各層均為 SPI放接,SPI意味著下面各層都是組件化可以被替換的刺啦,這也是dubbo比較好的一點(diǎn),主要功能組件都可以插件化替換纠脾。dubbo增強(qiáng)了JDK中的SPI功能玛瘸,在dubbo中其它各層都是使用擴(kuò)展點(diǎn)進(jìn)行提供服務(wù)的蜕青,dubbo增強(qiáng)的SPI增加了對(duì)擴(kuò)展點(diǎn) IoC 和 AOP 的支持,一個(gè)擴(kuò)展點(diǎn)可以直接 setter 注入其它擴(kuò)展點(diǎn)糊渊;并且不會(huì)一次性實(shí)例化擴(kuò)展點(diǎn)的所有實(shí)現(xiàn)類右核,這避免了有擴(kuò)展實(shí)現(xiàn)初始化很耗時(shí),但如果沒用上也加載渺绒,會(huì)很浪費(fèi)資源的情況贺喝,增強(qiáng)的SPI是在具體用某一個(gè)實(shí)現(xiàn)類時(shí)候才進(jìn)行實(shí)例化绎巨。后續(xù)會(huì)具體講解增強(qiáng)的SPI的實(shí)現(xiàn)原理缝其。
proxy 服務(wù)代理層:擴(kuò)展接口為 ProxyFactory,dubbo實(shí)現(xiàn)的SPI主要JavassistProxyFactory(默認(rèn)使用)和JdkProxyFactory瓶竭,用來(lái)對(duì)服務(wù)提供方和服務(wù)消費(fèi)方的服務(wù)進(jìn)行代理针炉。
registry 注冊(cè)中心層:封裝服務(wù)地址的注冊(cè)與發(fā)現(xiàn)挠他,擴(kuò)展接口為 Registry , RegistryService,Dubbo提供的擴(kuò)展接口實(shí)現(xiàn)為ZookeeperRegistry,RedisRegistry篡帕,MulticastRegistry殖侵,DubboRegistry。
擴(kuò)展接口RegistryFactory镰烧,dubbo提供的擴(kuò)展接口實(shí)現(xiàn)DubboRegistryFactory拢军,DubboRegistryFactory,RedisRegistryFactory怔鳖,ZookeeperRegistryFactory茉唉。cluster 路由層:封裝多個(gè)提供者的路由及負(fù)載均衡,并橋接注冊(cè)中心结执,
擴(kuò)展接口為 Cluster , Directory , Router ,LoadBalance度陆。monitor 監(jiān)控層:RPC 調(diào)用次數(shù)和調(diào)用時(shí)間監(jiān)控,擴(kuò)展接口為 MonitorFactory , Monitor , MonitorService献幔。
protocol 遠(yuǎn)程調(diào)用層:封將 RPC 調(diào)用懂傀,擴(kuò)展接口為 Protocol , Invoker , Exporter。
exchange 信息交換層:封裝請(qǐng)求響應(yīng)模式蜡感,同步轉(zhuǎn)異步蹬蚁,擴(kuò)展接口為 Exchanger , ExchangeChannel ,ExchangeClient , ExchangeServer
transport 網(wǎng)絡(luò)傳輸層:抽象 mina 和 netty 為統(tǒng)一接口擴(kuò)展接口為 Channel , Transporter , Client , Server , Codec
serialize 數(shù)據(jù)序列化層:可復(fù)用的一些工具,擴(kuò)展接口為 Serialization ,
ObjectInput , ObjectOutput , ThreadPool
關(guān)于dubbo擴(kuò)展點(diǎn)一個(gè)簡(jiǎn)單的例子:
以擴(kuò)展 Dubbo 的協(xié)議為例郑兴,在協(xié)議的實(shí)現(xiàn) jar 包內(nèi)放置文本文件: METAINF/dubbo/com.alibaba.dubbo.rpc.Protocol 犀斋,內(nèi)容為:
myprotocol=com.alibaba.user.MyProtocol
MyProtocol內(nèi)容如下:
package com.alibaba.user;
import com.alibaba.dubbo.rpc.Protocol;
public class MyProtocol implemenets Protocol {
// ...
}
配置模塊中的配置
Dubbo 配置模塊中,擴(kuò)展點(diǎn)均有對(duì)應(yīng)配置屬性或標(biāo)簽情连,通過(guò)配置指定使用哪個(gè)擴(kuò)展
實(shí)現(xiàn)闪水。比如:
<dubbo:protocol name="myprotocol" />
三、遠(yuǎn)程調(diào)用細(xì)節(jié)
3.1 服務(wù)提供者暴露一個(gè)服務(wù)的詳細(xì)過(guò)程
首先 ServiceConfig 類拿到對(duì)外提供服務(wù)的實(shí)際類 ref(如:UserServiceImpl),然后通過(guò) ProxyFactory 類的 getInvoker 方法使用 ref 生成一個(gè)
AbstractProxyInvoker 實(shí)例,到這一步就完成具體服務(wù)到 Invoker 的轉(zhuǎn)化球榆。
接下來(lái)就是 Invoker 轉(zhuǎn)換到 Exporter 的過(guò)程朽肥。Dubbo 處理服務(wù)暴露的關(guān)鍵就在 Invoker 轉(zhuǎn)換到 Exporter 的過(guò)程,上圖中的紅色部分持钉。Dubbo 協(xié)議的 Invoker 轉(zhuǎn)為 Exporter 發(fā)生在 DubboProtocol 類的
export 方法衡招,它主要是打開創(chuàng)建一個(gè)Netty Server 偵聽服務(wù),并接收客戶端發(fā)來(lái)的各種請(qǐng)求每强,通訊細(xì)節(jié)由 Dubbo 自己實(shí)現(xiàn)始腾,然后注冊(cè)服務(wù)到服務(wù)注冊(cè)中心。
3.2 服務(wù)消費(fèi)者消費(fèi)一個(gè)服務(wù)的詳細(xì)過(guò)程
- 首先 ReferenceConfig 類的 init 方法調(diào)用 Protocol 的 refer 方法生
成 Invoker 實(shí)例(如上圖中的紅色部分)空执,這是服務(wù)消費(fèi)的關(guān)鍵浪箭。接下來(lái)把
Invoker 轉(zhuǎn)換為客戶端需要的接口(如:UserServiceBo)。 - dubbo協(xié)議的invoker轉(zhuǎn)換為客戶端需要的接口是發(fā)生在DubboProtocol的refer方法辨绊,他主要是創(chuàng)建一個(gè)netty client 鏈接服務(wù)提供者奶栖,通訊細(xì)節(jié)由 Dubbo 自己實(shí)現(xiàn)。
四门坷、總結(jié)
本文簡(jiǎn)單的介紹了dubbo整體架構(gòu)宣鄙,后續(xù)具體介紹,dubbo增強(qiáng)的spi的實(shí)現(xiàn)默蚌,服務(wù)提供方如何發(fā)布服務(wù)冻晤,比如何時(shí)如何創(chuàng)建netty Server來(lái)監(jiān)聽服務(wù)消費(fèi)者的鏈接,何時(shí)如何注冊(cè)服務(wù)到服務(wù)治理中心绸吸;dubbo的filter鏈如何構(gòu)建鼻弧;服務(wù)消費(fèi)方如何消費(fèi)服務(wù),何時(shí)創(chuàng)建netty client....
歡迎大家加入知識(shí)星球锦茁,在知識(shí)星球里面我們會(huì)深入討論Java并發(fā)編程攘轩,以及JUC包源碼;Java類加載器原理;Spring,Springboot,Tomcat蜻势,Dubbo等開源框架的使用以及源碼剖析撑刺;分享作者從畢業(yè)到現(xiàn)在一路走來(lái)的學(xué)習(xí)經(jīng)驗(yàn)鹉胖,如何高效學(xué)習(xí)握玛,如何閱讀源碼;討論職業(yè)面試時(shí)候會(huì)經(jīng)常遇到的問(wèn)題以及如何作答甫菠,讀者可以識(shí)別下面二維碼加入: