Dubbo 同步異步調(diào)用

轉(zhuǎn)載自 http://dubbo.apache.org/books/dubbo-dev-book/implementation.html

實(shí)現(xiàn)細(xì)節(jié)

初始化過程細(xì)節(jié)

解析服務(wù)

基于 dubbo.jar 內(nèi)的META-INF/spring.handlers配置,Spring 在遇到 dubbo 名稱空間時(shí),會回調(diào)DubboNamespaceHandler丐谋。

所有 dubbo 的標(biāo)簽芍碧,都統(tǒng)一用DubboBeanDefinitionParser進(jìn)行解析,基于一對一屬性映射号俐,將 XML 標(biāo)簽解析為 Bean 對象泌豆。

在ServiceConfig.export()或ReferenceConfig.get()初始化時(shí),將 Bean 對象轉(zhuǎn)換 URL 格式吏饿,所有 Bean 屬性轉(zhuǎn)成 URL 的參數(shù)踪危。

然后將 URL 傳給協(xié)議擴(kuò)展點(diǎn),基于擴(kuò)展點(diǎn)的擴(kuò)展點(diǎn)自適應(yīng)機(jī)制猪落,根據(jù) URL 的協(xié)議頭贞远,進(jìn)行不同協(xié)議的服務(wù)暴露或引用。

暴露服務(wù)

1. 只暴露服務(wù)端口:

在沒有注冊中心笨忌,直接暴露提供者的情況下1蓝仲,ServiceConfig解析出的 URL 的格式為:dubbo://service-host/com.foo.FooService?version=1.0.0。

基于擴(kuò)展點(diǎn)自適應(yīng)機(jī)制官疲,通過 URL 的dubbo://協(xié)議頭識別袱结,直接調(diào)用DubboProtocol的export()方法,打開服務(wù)端口途凫。

2. 向注冊中心暴露服務(wù):

在有注冊中心垢夹,需要注冊提供者地址的情況下2,ServiceConfig解析出的 URL 的格式為:

registry://registry-host/com.alibaba.dubbo.registry.RegistryService?export=URL.encode("dubbo://service-host/com.foo.FooService?version=1.0.0")颖榜,

基于擴(kuò)展點(diǎn)自適應(yīng)機(jī)制棚饵,通過 URL 的registry://協(xié)議頭識別,就會調(diào)用RegistryProtocol的export()方法掩完,將export參數(shù)中的提供者 URL噪漾,先注冊到注冊中心。

再重新傳給Protocol擴(kuò)展點(diǎn)進(jìn)行暴露:dubbo://service-host/com.foo.FooService?version=1.0.0且蓬,然后基于擴(kuò)展點(diǎn)自適應(yīng)機(jī)制欣硼,通過提供者 URL 的dubbo://協(xié)議頭識別,就會調(diào)用DubboProtocol的export()方法恶阴,打開服務(wù)端口诈胜。

引用服務(wù)

1. 直連引用服務(wù):

在沒有注冊中心,直連提供者的情況下3冯事,ReferenceConfig解析出的 URL 的格式為:

dubbo://service-host/com.foo.FooService?version=1.0.0焦匈。

基于擴(kuò)展點(diǎn)自適應(yīng)機(jī)制,通過 URL 的dubbo://協(xié)議頭識別昵仅,直接調(diào)用DubboProtocol的refer()方法缓熟,返回提供者引用累魔。

2. 從注冊中心發(fā)現(xiàn)引用服務(wù):

在有注冊中心,通過注冊中心發(fā)現(xiàn)提供者地址的情況下4够滑,ReferenceConfig解析出的 URL 的格式為:

registry://registry-host/com.alibaba.dubbo.registry.RegistryService?refer=URL.encode("consumer://consumer-host/com.foo.FooService?version=1.0.0")垦写。

基于擴(kuò)展點(diǎn)自適應(yīng)機(jī)制,通過 URL 的registry://協(xié)議頭識別彰触,就會調(diào)用RegistryProtocol的refer()方法梯投,基于refer參數(shù)中的條件,查詢提供者 URL况毅,如:dubbo://service-host/com.foo.FooService?version=1.0.0分蓖。

基于擴(kuò)展點(diǎn)自適應(yīng)機(jī)制,通過提供者 URL 的dubbo://協(xié)議頭識別俭茧,就會調(diào)用DubboProtocol的refer()方法咆疗,得到提供者引用。

然后RegistryProtocol將多個(gè)提供者引用母债,通過Cluster擴(kuò)展點(diǎn)午磁,偽裝成單個(gè)提供者引用返回。

攔截服務(wù)

基于擴(kuò)展點(diǎn)自適應(yīng)機(jī)制毡们,所有的Protocol擴(kuò)展點(diǎn)都會自動套上Wrapper類迅皇。

基于ProtocolFilterWrapper類,將所有Filter組裝成鏈衙熔,在鏈的最后一節(jié)調(diào)用真實(shí)的引用登颓。

基于ProtocolListenerWrapper類,將所有InvokerListener和ExporterListener組裝集合红氯,在暴露和引用前后框咙,進(jìn)行回調(diào)。

包括監(jiān)控在內(nèi)痢甘,所有附加功能喇嘱,全部通過Filter攔截實(shí)現(xiàn)。

遠(yuǎn)程調(diào)用細(xì)節(jié)

服務(wù)提供者暴露一個(gè)服務(wù)的詳細(xì)過程


上圖是服務(wù)提供者暴露服務(wù)的主過程:

首先ServiceConfig類拿到對外提供服務(wù)的實(shí)際類 ref(如:HelloWorldImpl),然后通過ProxyFactory類的getInvoker方法使用 ref 生成一個(gè)AbstractProxyInvoker實(shí)例塞栅,到這一步就完成具體服務(wù)到Invoker的轉(zhuǎn)化者铜。接下來就是Invoker轉(zhuǎn)換到Exporter的過程。

Dubbo 處理服務(wù)暴露的關(guān)鍵就在Invoker轉(zhuǎn)換到Exporter的過程放椰,上圖中的紅色部分作烟。下面我們以 Dubbo 和 RMI 這兩種典型協(xié)議的實(shí)現(xiàn)來進(jìn)行說明:

Dubbo 的實(shí)現(xiàn)

Dubbo 協(xié)議的Invoker轉(zhuǎn)為Exporter發(fā)生在DubboProtocol類的export方法,它主要是打開 socket 偵聽服務(wù)砾医,并接收客戶端發(fā)來的各種請求拿撩,通訊細(xì)節(jié)由 Dubbo 自己實(shí)現(xiàn)。

RMI 的實(shí)現(xiàn)

RMI 協(xié)議的Invoker轉(zhuǎn)為Exporter發(fā)生在RmiProtocol類的export方法如蚜,它通過 Spring 或 Dubbo 或 JDK 來實(shí)現(xiàn) RMI 服務(wù)绷雏,通訊細(xì)節(jié)這一塊由 JDK 底層來實(shí)現(xiàn)头滔,這就省了不少工作量怖亭。

服務(wù)消費(fèi)者消費(fèi)一個(gè)服務(wù)的詳細(xì)過程

上圖是服務(wù)消費(fèi)的主過程:

首先ReferenceConfig類的init方法調(diào)用Protocol的refer方法生成Invoker實(shí)例(如上圖中的紅色部分)涎显,這是服務(wù)消費(fèi)的關(guān)鍵。接下來把Invoker轉(zhuǎn)換為客戶端需要的接口(如:HelloWorld)兴猩。

關(guān)于每種協(xié)議如 RMI/Dubbo/Web service 等它們在調(diào)用refer方法生成Invoker實(shí)例的細(xì)節(jié)和上一章節(jié)所描述的類似期吓。

滿眼都是 Invoker

由于Invoker是 Dubbo 領(lǐng)域模型中非常重要的一個(gè)概念,很多設(shè)計(jì)思路都是向它靠攏倾芝。這就使得Invoker滲透在整個(gè)實(shí)現(xiàn)代碼里讨勤,對于剛開始接觸 Dubbo 的人,確實(shí)容易給搞混了晨另。下面我們用一個(gè)精簡的圖來說明最重要的兩種Invoker:服務(wù)提供Invoker和服務(wù)消費(fèi)Invoker:

為了更好的解釋上面這張圖潭千,我們結(jié)合服務(wù)消費(fèi)和提供者的代碼示例來進(jìn)行說明:

服務(wù)消費(fèi)者代碼:

public? class? DemoClientAction{

??????? private DemoService demoService;

??????? public void setDemoService(DemoService demoService){

??????????????? this.demoService = demoService;? ?

???????? }

????????? public void start(){?

? ? ???????????? String hello = demoService.sayHello("world"+ i);? ?

?????????? }

}

上面代碼中的DemoService就是上圖中服務(wù)消費(fèi)端的 proxy,用戶代碼通過這個(gè) proxy 調(diào)用其對應(yīng)的Invoker5借尿,而該Invoker實(shí)現(xiàn)了真正的遠(yuǎn)程服務(wù)調(diào)用刨晴。

服務(wù)提供者代碼:

public class DemoService Implimplements?? DemoService{

?????????? public String sayHello(String name)throws RemoteException{

?????????????????? return"Hello "+ name;? ?

??????????? }

}

上面這個(gè)類會被封裝成為一個(gè)AbstractProxyInvoker實(shí)例,并新生成一個(gè)Exporter實(shí)例路翻。這樣當(dāng)網(wǎng)絡(luò)通訊層收到一個(gè)請求后狈癞,會找到對應(yīng)的Exporter實(shí)例,并調(diào)用它所對應(yīng)的AbstractProxyInvoker實(shí)例茂契,從而真正調(diào)用了服務(wù)提供者的代碼蝶桶。Dubbo 里還有一些其他的Invoker類,但上面兩種是最重要的掉冶。

遠(yuǎn)程通訊細(xì)節(jié)

協(xié)議頭約定

線程派發(fā)模型

Dispather:all,direct,message,execution,connection

ThreadPool:fixed,cached

? ? ? ? ? ? ? ?

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末真竖,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子厌小,更是在濱河造成了極大的恐慌恢共,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件召锈,死亡現(xiàn)場離奇詭異旁振,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)涨岁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進(jìn)店門拐袜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人梢薪,你說我怎么就攤上這事蹬铺。” “怎么了秉撇?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵甜攀,是天一觀的道長秋泄。 經(jīng)常有香客問我,道長规阀,這世上最難降的妖魔是什么恒序? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮谁撼,結(jié)果婚禮上歧胁,老公的妹妹穿的比我還像新娘。我一直安慰自己厉碟,他們只是感情好喊巍,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著箍鼓,像睡著了一般崭参。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上款咖,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天何暮,我揣著相機(jī)與錄音,去河邊找鬼之剧。 笑死郭卫,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的背稼。 我是一名探鬼主播贰军,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蟹肘!你這毒婦竟也來了词疼?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤帘腹,失蹤者是張志新(化名)和其女友劉穎贰盗,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體阳欲,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡舵盈,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了球化。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片秽晚。...
    茶點(diǎn)故事閱讀 40,675評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖筒愚,靈堂內(nèi)的尸體忽然破棺而出赴蝇,到底是詐尸還是另有隱情,我是刑警寧澤巢掺,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布句伶,位于F島的核電站劲蜻,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏考余。R本人自食惡果不足惜先嬉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望秃殉。 院中可真熱鬧坝初,春花似錦、人聲如沸钾军。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽吏恭。三九已至,卻和暖如春重罪,著一層夾襖步出監(jiān)牢的瞬間樱哼,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工剿配, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留搅幅,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓呼胚,卻偏偏與公主長得像茄唐,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子蝇更,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內(nèi)容