天天看點

Dubbo源碼解析實戰 - 服務暴露原理人性的拷問全局總覽參考

dubbo面試中比較喜歡問的兩個點:服務釋出和服務引用.

人性的拷問

  • 服務釋出過程中做了哪些事
  • dubbo都有哪些協定,他們之間有什麼特點,預設值是什麼
  • 什麼是本地暴露和遠端暴露,他們的差別

直入主題

從啟動日志說起

Dubbo源碼解析實戰 - 服務暴露原理人性的拷問全局總覽參考

這裡不同顔色的框将關鍵的地方畫了出來,一共有6種顔色, 從上到下

  1. 暴露本地服務
  2. 暴露遠端服務
  3. 啟動netty
  4. 連接配接zookeeper
  5. 到zookeeper注冊
  6. 監聽zookeeper

全局總覽

先看官方文檔說明

服務提供者暴露一個服務的詳細過程

  • 服務提供者暴露服務的主過程
Dubbo源碼解析實戰 - 服務暴露原理人性的拷問全局總覽參考

首先 

ServiceConfig

 類拿到對外提供服務的實際類 ref(如:HelloWorldImpl),然後通過 

ProxyFactory

 類的

getInvoker

 方法使用 ref 生成一個 

AbstractProxyInvoker

 執行個體,到這一步就完成具體服務到 Invoker 的轉化。

接下來就是 Invoker 轉換到 Exporter 的過程。

Dubbo源碼解析實戰 - 服務暴露原理人性的拷問全局總覽參考

看源碼,很多人最常問的一句話就是,怎麼入手,也就是切入點.那麼我們還是以開頭的日志為例,來找一個這個切入點

仔細看輸出日志,就會發現在暴露本地服務之前,有一句很重要的日志,就是

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源碼解析實戰 - 服務暴露原理人性的拷問全局總覽參考
Dubbo源碼解析實戰 - 服務暴露原理人性的拷問全局總覽參考
Dubbo源碼解析實戰 - 服務暴露原理人性的拷問全局總覽參考

重點!!!

Dubbo源碼解析實戰 - 服務暴露原理人性的拷問全局總覽參考
Dubbo源碼解析實戰 - 服務暴露原理人性的拷問全局總覽參考

這個dubbo.properties檔案是怎麼時候加載的,好像我根本沒有設定,另外這個dubbo.properties檔案的名字能不能改?

Dubbo源碼解析實戰 - 服務暴露原理人性的拷問全局總覽參考
  • 同理,對于log4j.xml檔案
Dubbo源碼解析實戰 - 服務暴露原理人性的拷問全局總覽參考

接下來繼續往下走,下面這裡就是我們的第二道面試題

Dubbo源碼解析實戰 - 服務暴露原理人性的拷問全局總覽參考
  • 因為dubbo是支援多協定的,看文檔原話
Dubbo源碼解析實戰 - 服務暴露原理人性的拷問全局總覽參考
  • Dubbo支援多種協定,預設使用的是dubbo協定 Dubbo協定

到了第三個面試題,也是服務釋出的重點,

本地暴露和遠端暴露

Dubbo源碼解析實戰 - 服務暴露原理人性的拷問全局總覽參考

為什麼會有本地暴露和遠端暴露呢?

不從場景考慮讨論技術的沒有意義是.在dubbo中我們一個服務可能既是Provider,又是Consumer,是以就存在他自己調用自己服務的情況,如果再通過網絡去通路,那自然是舍近求遠

是以他是有本地暴露服務的這個設計

  • 本地暴露是暴露在JVM中,不需要網絡通信
  • 遠端暴露是将ip,端口等資訊暴露給遠端用戶端,調用時需要網絡通信
Dubbo源碼解析實戰 - 服務暴露原理人性的拷問全局總覽參考
Dubbo源碼解析實戰 - 服務暴露原理人性的拷問全局總覽參考

從上圖可知,這裡用到了Adaptive,

  • 點進ProxyFactory檢視源碼
Dubbo源碼解析實戰 - 服務暴露原理人性的拷問全局總覽參考

@Adaptive注解打在類上和方法上,他們是有差別的

在方法上,就會生成動态編譯的Adaptive類,下面就介紹一下怎麼看這個動态編譯類的源碼

  • 首先要将這個log4j的level調整為DEBUG
Dubbo源碼解析實戰 - 服務暴露原理人性的拷問全局總覽參考

為什麼需要調整成DEBUG,

比如下圖

Dubbo源碼解析實戰 - 服務暴露原理人性的拷問全局總覽參考

打開DEBUG後,我們重新啟動,就會看到日志有如下輸出,這段就是相關代碼,我們根據包名建立檔案,如下

Dubbo源碼解析實戰 - 服務暴露原理人性的拷問全局總覽參考
Dubbo源碼解析實戰 - 服務暴露原理人性的拷問全局總覽參考

我們在getInvoker方法上打上斷點,重新開機一下.

Dubbo源碼解析實戰 - 服務暴露原理人性的拷問全局總覽參考
Dubbo源碼解析實戰 - 服務暴露原理人性的拷問全局總覽參考
Dubbo源碼解析實戰 - 服務暴露原理人性的拷問全局總覽參考

由上圖知道,本地暴露的url是以injvm開頭的,下面來看下遠端暴露,其實這個也是回答本地暴露和遠端暴露差別的一個回答點.面試回答要的并不是一個滿分的答案,而是從一些細節中,看出一個人,是否真的研究過源碼.

Dubbo源碼解析實戰 - 服務暴露原理人性的拷問全局總覽參考

還是回到開頭那句話,dubbo命名是很規範的,從Wrapper這個命名,其實可以和Spring的Bean Wrapper,以及裝飾者設計模式聯系起來.同時可以看看文檔中的編碼約定

參考