dubbo概述
dubbo是阿裡巴巴開源出來的一個分布式服務架構,緻力于提供高性能和透明化的rpc遠端服務調用方案,以及作為soa服務治理的方案。它的核心功能包括:
這裡我們隻是補充一下從源碼具體實作角度來看的某些細節方面,包括invoker、extensionloader等方面。任何官方已經介紹過的細節,我們不做畫蛇添足,官方文檔已經足夠詳實了,這篇文檔的定位是補充實作的相關細節,是基于我在往dubbo添加web service協定過程中,所碰到過的一些困難。
服務提供者暴露一個服務的詳細過程

上圖是服務提供者暴露服務的主過程:
首先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底層來實作,這就省了不少工作量。
服務消費者消費一個服務的詳細過程
上圖是服務消費的主過程:
首先referenceconfig類的init方法調用protocol的refer方法生成invoker執行個體(如上圖中的紅色部分),這是服務消費的關鍵。接下來把invoker轉換為用戶端需要的接口(如:helloworld)。
關于每種協定如rmi/dubbo/web service等它們在調用refer方法生成invoker執行個體的細節和上一章節所描述的類似。
滿眼都是invoker
由于invoker是dubbo領域模型中非常重要的一個概念,很多設計思路都是向它靠攏。這就使得invoker滲透在整個實作代碼裡,對于剛開始接觸dubbo的人,确實容易給搞混了。
為了更好的解釋上面這張圖,我們結合服務消費和提供者的代碼示例來進行說明:
#服務消費者代碼
上面代碼中的’demoservice’就是上圖中服務消費端的proxy,使用者代碼通過這個proxy調用其對應的invoker(dubboinvoker、 hessianrpcinvoker、 injvminvoker、 rmiinvoker、 webserviceinvoker中的任何一個),而該invoker實作了真正的遠端服務調用。
上面這個類會被封裝成為一個abstractproxyinvoker執行個體,并新生成一個exporter執行個體。這樣當網絡通訊層收到一個請求後,會找到對應的exporter執行個體,并調用它所對應的abstractproxyinvoker執行個體,進而真正調用了服務提供者的代碼。
dubbo裡還有一些其他的invoker類,但上面兩種是最重要的。
extensionloader的完整分析
extensionloader是dubbo中一個非常重要的類,剛接觸dubbo源碼的人看這個類的時候也多少會有點困惑,這個類非常重要,它就像是廚房裡的“大廚”,按照使用者的随時需要把各種“食材”烹調出來。
我們結合具體代碼詳細說一下extensionloader的實作,下面是serviceconfig類裡的一行代碼:
private static final protocol protocol = extensionloader.getextensionloader(protocol.class).getadaptiveextension();
在這個過程中最重要的兩個方法是getextensionclasses和createadaptiveextensionclass(圖中紅色部分),下面詳細對這兩個方法進行分析:
#getextensionclasses
這個方法主要讀取meta-inf/services/目錄下對應檔案内容,在本示例代碼中,是讀取meta-inf/services/com.alibaba.dubbo.rpc.protocol檔案中的内容,具體内容如下:
com.alibaba.dubbo.registry.support.registryprotocol
com.alibaba.dubbo.rpc.protocol.protocolfilterwrapper
com.alibaba.dubbo.rpc.protocol.protocollistenerwrapper
com.alibaba.dubbo.rpc.protocol.dubbo.dubboprotocol
com.alibaba.dubbo.rpc.protocol.injvm.injvmprotocol
com.alibaba.dubbo.rpc.protocol.rmi.rmiprotocol
com.alibaba.dubbo.rpc.protocol.hessian.hessianprotocol
com.alibaba.dubbo.rpc.protocol.webservice.webserviceprotocol
它分析該檔案中的每一行(每一行對應一個類),分析這些類,如果發現有哪個類的annotation是@adaptive,則找到對應的adaptiveclass了,但由于protocol檔案裡沒有哪個類的annotation是@adaptive,是以在這個例子中該方法沒找到對應的adaptiveclass。
#createadaptiveextensionclass
該方法是在getextensionclasses方法找不到adaptiveclass的情況下被調用,該方法主要是通過位元組碼的方式在記憶體中新生成一個類,它具有adaptiveclass的功能,protocol就是通過這種方式獲得adaptiveclass類的。
adaptiveclass類的作用是能在運作時動态判斷具體是要調用哪個類的方法,更多關于adaptiveclass的内容請參考dubbo官方文檔。