dubbo面試中比較喜歡問的兩個點:服務發佈和服務引用.
人性的拷問
- 服務發佈過程中做了哪些事
- dubbo都有哪些協議,他們之間有什麼特點,缺省值是什麼
- 什麼是本地暴露和遠程暴露,他們的區別
直入主題
從啓動日誌說起
這裏不同顏色的框將關鍵的地方畫了出來,一共有6種顏色, 從上到下
- 暴露本地服務
- 暴露遠程服務
- 啓動netty
- 連接zookeeper
- 到zookeeper註冊
- 監聽zookeeper
全局總覽
先看官方文檔說明
服務提供者暴露一個服務的詳細過程
- 服務提供者暴露服務的主過程
首先 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
該打印在今年八月被移除,具體原因不明, 留待日後分析,先繼續經典版本源碼
定位到了ServiceBean
這個類
- 繼承體系圖
繼續按照經典版本源碼講解,這裏最新版源碼由於刪除了相關接口
從這個圖我們看到了許多和spring有關的東西,還發現了一個重要的接口,那就是ApplicationListener
就是spring的事件機制(event).什麼是事件機制呢?
就比如監聽spring容器初始化完成.那我們就定位到這行日誌的位置,往下debug
重點!!!
這個dubbo.properties文件是怎麼時候加載的,好像我根本沒有設置,另外這個dubbo.properties文件的名字能不能改?
- 同理,對於log4j.xml文件
接下來繼續往下走,下面這裏就是我們的第二道面試題
- 因爲dubbo是支持多協議的,看文檔原話
- Dubbo支持多種協議,默認使用的是dubbo協議
Dubbo協議
到了第三個面試題,也是服務發佈的重點,本地暴露和遠程暴露
爲什麼會有本地暴露和遠程暴露呢?
不從場景考慮討論技術的沒有意義是.在dubbo中我們一個服務可能既是Provider,又是Consumer,因此就存在他自己調用自己服務的情況,如果再通過網絡去訪問,那自然是捨近求遠
因此他是有本地暴露服務的這個設計
- 本地暴露是暴露在JVM中,不需要網絡通信
- 遠程暴露是將ip,端口等信息暴露給遠程客戶端,調用時需要網絡通信
從上圖可知,這裏用到了Adaptive,
- 點進ProxyFactory查看源碼
@Adaptive註解打在類上和方法上,他們是有區別的
在方法上,就會生成動態編譯的Adaptive類,下面就介紹一下怎麼看這個動態編譯類的源碼
- 首先要將這個log4j的level調整爲DEBUG
爲什麼需要調整成DEBUG,
比如下圖
打開DEBUG後,我們重新啓動,就會看到日誌有如下輸出,這段就是相關代碼,我們根據包名新建文件,如下
我們在getInvoker方法上打上斷點,重啓一下.
由上圖知道,本地暴露的url是以injvm開頭的,下面來看下遠程暴露,其實這個也是回答本地暴露和遠程暴露區別的一個回答點.面試回答要的並不是一個滿分的答案,而是從一些細節中,看出一個人,是否真的研究過源碼.
還是回到開頭那句話,dubbo命名是很規範的,從Wrapper這個命名,其實可以和Spring的Bean Wrapper,以及裝飾者設計模式聯繫起來.同時可以看看文檔中的編碼約定