dubbo面試中比較喜歡問的兩個點:服務(wù)發(fā)布和服務(wù)引用.
# 人性的拷問
- 服務(wù)發(fā)布過程中做了哪些事
- dubbo都有哪些協(xié)議,他們之間有什么特點,缺省值是什么
- 什么是本地暴露和遠程暴露,他們的區(qū)別
直入主題
從啟動日志說起
![](
https://img-blog.csdnimg
.cn/20191124151625334.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9qYXZhZWRnZS5ibG9nLmNzZG4ubmV0,size_1,color_FFFFFF,t_70)
這里不同顏色的框?qū)㈥P(guān)鍵的地方畫了出來,一共有6種顏色, 從上到下
1. 暴露本地服務(wù)
2. 暴露遠程服務(wù)
3. 啟動netty
4. 連接zookeeper
5. 到zookeeper注冊
6. 監(jiān)聽zookeeper
# 全局總覽
先看官方文檔說明
## 服務(wù)提供者暴露一個服務(wù)的詳細過程
- 服務(wù)提供者暴露服務(wù)的主過程
![](https://img-blog.csdnimg.cn/20191124160150667.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9qYXZhZWRnZS5ibG9nLmNzZG4ubmV0,size_1,color_FFFFFF,t_70)
首先 `ServiceConfig` 類拿到對外提供服務(wù)的實際類 ref(如:HelloWorldImpl),然后通過 `ProxyFactory` 類的 `getInvoker` 方法使用 ref 生成一個 `AbstractProxyInvoker` 實例,到這一步就完成具體服務(wù)到 Invoker 的轉(zhuǎn)化。
接下來就是 Invoker 轉(zhuǎn)換到 Exporter 的過程。
![](https://img-blog.csdnimg.cn/20191124161756667.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9qYXZhZWRnZS5ibG9nLmNzZG4ubmV0,size_1,color_FFFFFF,t_70)
看源碼,很多人最常問的一句話就是,怎么入手,也就是切入點.那么我們還是以開頭的日志為例,來找一個這個切入點
仔細看輸出日志,就會發(fā)現(xiàn)在暴露本地服務(wù)之前,有一句很重要的日志,就是
```bash
The service ready on spring started. service: com.alibaba.dubbo.demo.DemoService, dubbo version: 2.0.0, current host: 127.0.0.1
```
> 該打印在今年八月被移除,具體原因不明, 留待日后分析,先繼續(xù)經(jīng)典版本源碼
> ![]
> ![](https://img-blog.csdnimg.cn/2019112416565177.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9qYXZhZWRnZS5ibG9nLmNzZG4ubmV0,size_1,color_FFFFFF,t_70)
定位到了`ServiceBean`這個類
- 繼承體系圖
![](https://img-blog.csdnimg.cn/20191124165857776.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9qYXZhZWRnZS5ibG9nLmNzZG4ubmV0,size_1,color_FFFFFF,t_70)
> 繼續(xù)按照經(jīng)典版本源碼講解,這里最新版源碼由于刪除了相關(guān)接口
從這個圖我們看到了許多和spring有關(guān)的東西,還發(fā)現(xiàn)了一個重要的接口,那就是`ApplicationListener`
就是spring的事件機制(event).什么是事件機制呢?
就比如監(jiān)聽spring
容器初始化完成.那我們就定位到這行日志的位置,往下debug
![](https://img-blog.csdnimg.cn/20191124170659797.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9qYXZhZWRnZS5ibG9nLmNzZG4ubmV0,size_1,color_FFFFFF,t_70)
![](https://img-blog.csdnimg.cn/20191124170708847.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9qYXZhZWRnZS5ibG9nLmNzZG4ubmV0,size_1,color_FFFFFF,t_70)
![](https://img-blog.csdnimg.cn/20191124170721312.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9qYXZhZWRnZS5ibG9nLmNzZG4ubmV0,size_1,color_FFFFFF,t_70)
重點!!!
![](https://img-blog.csdnimg.cn/20191124171616267.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9qYXZhZWRnZS5ibG9nLmNzZG4ubmV0,size_1,color_FFFFFF,t_70)
![](https://img-blog.csdnimg.cn/20191124171851867.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9qYXZhZWRnZS5ibG9nLmNzZG4ubmV0,size_1,color_FFFFFF,t_70)
這個dubbo.properties文件是怎么時候加載的,好像我根本沒有設(shè)置,另外這個dubbo.properties文件的名字能不能改?
![](https://img-blog.csdnimg.cn/20191124195126940.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9qYXZhZWRnZS5ibG9nLmNzZG4ubmV0,size_1,color_FFFFFF,t_70)
- 同理,對于log4j.xml文件
![](https://img-blog.csdnimg.cn/20191124195351829.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9qYXZhZWRnZS5ibG9nLmNzZG4ubmV0,size_16,color_FFFFFF,t_70)
接下來繼續(xù)往下走,下面這里就是我們的第二道面試題
![](https://img-blog.csdnimg.cn/20191124195620539.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9qYXZhZWRnZS5ibG9nLmNzZG4ubmV0,size_1,color_FFFFFF,t_70)
- 因為dubbo是支持多協(xié)議的,看文檔原話
![](https://img-blog.csdnimg.cn/20191124195642846.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9qYXZhZWRnZS5ibG9nLmNzZG4ubmV0,size_1,color_FFFFFF,t_70)
- Dubbo支持多種協(xié)議,默認使用的是dubbo協(xié)議
(https://blog.csdn.net/qq_33589510/article/details/103108713)
到了第三個面試題,也是服務(wù)發(fā)布的重點,`本地暴露和遠程暴露`
![](https://img-blog.csdnimg.cn/20191124201218464.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9qYXZhZWRnZS5ibG9nLmNzZG4ubmV0,size_1,color_FFFFFF,t_70)
為什么會有本地暴露和遠程暴露呢?
不從場景考慮討論技術(shù)的沒有意義是.在dubbo中我們一個服務(wù)可能既是Provider,又是Consumer,因此就存在他自己調(diào)用自己服務(wù)的情況,如果再通過網(wǎng)絡(luò)去訪問,那自然是舍近求遠
因此他是有本地暴露服務(wù)的這個設(shè)計
- 本地暴露是暴露在JVM中,不需要網(wǎng)絡(luò)通信
- 遠程暴露是將ip,端口等信息暴露給遠程客戶端,調(diào)用時需要網(wǎng)絡(luò)通信
![](https://img-blog.csdnimg.cn/20191124202252323.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9qYXZhZWRnZS5ibG9nLmNzZG4ubmV0,size_1,color_FFFFFF,t_70)
![](https://img-blog.csdnimg.cn/20191124202414239.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9qYXZhZWRnZS5ibG9nLmNzZG4ubmV0,size_1,color_FFFFFF,t_70)
從上圖可知,這里用到了Adaptive,
- 點進ProxyFactory查看源碼
![](https://img-blog.csdnimg.cn/20191124201927649.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9qYXZhZWRnZS5ibG9nLmNzZG4ubmV0,size_1,color_FFFFFF,t_70)
@Adaptive注解打在類上和方法上,他們是有區(qū)別的
在方法上,就會生成動態(tài)編譯的Adaptive類,下面就介紹一下怎么看這個動態(tài)編譯類的源碼
- 首先要將這個log4j的level調(diào)整為DEBUG
![](https://img-blog.csdnimg.cn/20191124202701924.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9qYXZhZWRnZS5ibG9nLmNzZG4ubmV0,size_1,color_FFFFFF,t_70)
為什么需要調(diào)整成DEBUG,
比如下圖
![](https://img-blog.csdnimg.cn/20191124203107893.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9qYXZhZWRnZS5ibG9nLmNzZG4ubmV0,size_1,color_FFFFFF,t_70)
打開DEBUG后,我們重新啟動,就會看到日志有如下輸出,這段就是相關(guān)代碼,我們根據(jù)包名新建文件,如下
![](https://img-blog.csdnimg.cn/20191124203137536.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9qYXZhZWRnZS5ibG9nLmNzZG4ubmV0,size_1,color_FFFFFF,t_70)
![](https://img-blog.csdnimg.cn/20191124203245946.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9qYXZhZWRnZS5ibG9nLmNzZG4ubmV0,size_1,color_FFFFFF,t_70)
我們在getInvoker方法上打上斷點,重啟一下.
![](https://img-blog.csdnimg.cn/2019112420331334.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9qYXZhZWRnZS5ibG9nLmNzZG4ubmV0,size_1,color_FFFFFF,t_70)
![](https://img-blog.csdnimg.cn/20191124203346500.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9qYXZhZWRnZS5ibG9nLmNzZG4ubmV0,size_1,color_FFFFFF,t_70)
![](https://img-blog.csdnimg.cn/20191124203355960.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9qYXZhZWRnZS5ibG9nLmNzZG4ubmV0,size_1,color_FFFFFF,t_70)
由上圖知道,本地暴露的url是以injvm開頭的,下面來看下遠程暴露,其實這個也是回答本地暴露和遠程暴露區(qū)別的一個回答點.面試回答要的并不是一個滿分的答案,而是從一些細節(jié)中,看出一個人,是否真的研究過源碼.
![](https://img-blog.csdnimg.cn/20191124203417820.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9qYXZhZWRnZS5ibG9nLmNzZG4ubmV0,size_1,color_FFFFFF,t_70)
還是回到開頭那句話,dubbo命名是很規(guī)范的,從Wr
apper這個命名,其實可以和Spring的Bean Wrapper,以及裝飾者設(shè)計模式聯(lián)系起來.同時可以看看文檔中的編碼約定
# 參考
- https://www.jianshu
.com/p/60a9263f2ee2
-