dubbo面試中比較喜歡問的兩個點:服務釋出和服務引用.
人性的拷問
- 服務釋出過程中做了哪些事
- dubbo都有哪些協定,他們之間有什麼特點,預設值是什麼
- 什麼是本地暴露和遠端暴露,他們的差別
直入主題
從啟動日志說起

這裡不同顔色的框将關鍵的地方畫了出來,一共有6種顔色, 從上到下
- 暴露本地服務
- 暴露遠端服務
- 啟動netty
- 連接配接zookeeper
- 到zookeeper注冊
- 監聽zookeeper
全局總覽
先看官方文檔說明
服務提供者暴露一個服務的詳細過程
- 服務提供者暴露服務的主過程
Dubbo源碼解析實戰 - 服務暴露原理人性的拷問全局總覽參考
首先
ServiceConfig
類拿到對外提供服務的實際類 ref(如:HelloWorldImpl),然後通過
ProxyFactory
類的
getInvoker
方法使用 ref 生成一個
AbstractProxyInvoker
執行個體,到這一步就完成具體服務到 Invoker 的轉化。
接下來就是 Invoker 轉換到 Exporter 的過程。
看源碼,很多人最常問的一句話就是,怎麼入手,也就是切入點.那麼我們還是以開頭的日志為例,來找一個這個切入點
仔細看輸出日志,就會發現在暴露本地服務之前,有一句很重要的日志,就是
The service ready on spring started. service: com.alibaba.dubbo.demo.DemoService, dubbo version: 2.0.0, current host: 127.0.0.1
該列印在今年八月被移除,具體原因不明, 留待日後分析,先繼續經典版本源碼![]()
Dubbo源碼解析實戰 - 服務暴露原理人性的拷問全局總覽參考 ![]()
Dubbo源碼解析實戰 - 服務暴露原理人性的拷問全局總覽參考
定位到了
ServiceBean
這個類
- 繼承體系圖
Dubbo源碼解析實戰 - 服務暴露原理人性的拷問全局總覽參考
繼續按照經典版本源碼講解,這裡最新版源碼由于删除了相關接口
從這個圖我們看到了許多和spring有關的東西,還發現了一個重要的接口,那就是
ApplicationListener
就是spring的事件機制(event).什麼是事件機制呢?
就比如監聽spring容器初始化完成.那我們就定位到這行日志的位置,往下debug
重點!!!
這個dubbo.properties檔案是怎麼時候加載的,好像我根本沒有設定,另外這個dubbo.properties檔案的名字能不能改?
- 同理,對于log4j.xml檔案
Dubbo源碼解析實戰 - 服務暴露原理人性的拷問全局總覽參考
接下來繼續往下走,下面這裡就是我們的第二道面試題
- 因為dubbo是支援多協定的,看文檔原話
Dubbo源碼解析實戰 - 服務暴露原理人性的拷問全局總覽參考 - Dubbo支援多種協定,預設使用的是dubbo協定 Dubbo協定
到了第三個面試題,也是服務釋出的重點,
本地暴露和遠端暴露
為什麼會有本地暴露和遠端暴露呢?
不從場景考慮讨論技術的沒有意義是.在dubbo中我們一個服務可能既是Provider,又是Consumer,是以就存在他自己調用自己服務的情況,如果再通過網絡去通路,那自然是舍近求遠
是以他是有本地暴露服務的這個設計
- 本地暴露是暴露在JVM中,不需要網絡通信
- 遠端暴露是将ip,端口等資訊暴露給遠端用戶端,調用時需要網絡通信
從上圖可知,這裡用到了Adaptive,
- 點進ProxyFactory檢視源碼
Dubbo源碼解析實戰 - 服務暴露原理人性的拷問全局總覽參考
@Adaptive注解打在類上和方法上,他們是有差別的
在方法上,就會生成動态編譯的Adaptive類,下面就介紹一下怎麼看這個動态編譯類的源碼
- 首先要将這個log4j的level調整為DEBUG
Dubbo源碼解析實戰 - 服務暴露原理人性的拷問全局總覽參考
為什麼需要調整成DEBUG,
比如下圖
打開DEBUG後,我們重新啟動,就會看到日志有如下輸出,這段就是相關代碼,我們根據包名建立檔案,如下
我們在getInvoker方法上打上斷點,重新開機一下.
由上圖知道,本地暴露的url是以injvm開頭的,下面來看下遠端暴露,其實這個也是回答本地暴露和遠端暴露差別的一個回答點.面試回答要的并不是一個滿分的答案,而是從一些細節中,看出一個人,是否真的研究過源碼.
還是回到開頭那句話,dubbo命名是很規範的,從Wrapper這個命名,其實可以和Spring的Bean Wrapper,以及裝飾者設計模式聯系起來.同時可以看看文檔中的編碼約定