Dubbo源碼學習總結系列一 整體認識

        本文寫做時,dubbo最高版本是V2.6.0。  寫這篇文章主要想回答如下4個問題:spring

        1、dubbo是什麼?完成了哪些主要需求?服務器

        2、dubbo適用於什麼場景?網絡

        3、dubbo的整體架構是什麼樣的?架構

        4、dubbo調用的過程是什麼樣的?負載均衡

        下面就一一道來。框架

    

        1、dubbo是什麼?完成了哪些主要需求?異步

        dubbo是一個面向服務治理(SOA)的分佈式RPC框架。分佈式

        它主要實現瞭如下一些需求:ide

        RPC方面:微服務

        實現了基本的RPC過程,開發了DubboProtocol做爲默認的實現,並集成了Hession,RMI,HTTP,WebService,Thrift(被改造,與原Thrift不兼容),Rest等遠程過程調用框架。基本組成爲:Protocol(默認dubbo),Invoker,Transporter(默認netty),Codec2(默認Hession2編碼)。

        編解碼方面提供了Hession2(默認,阿里修改過的hessian lite)、dubbo、Java、JSON、Thrift(與原Thrift不兼容)、Kryo、FST序列化。

        DubboProtocol實現了同步調用、異步請求、回調方法設置、本地調用等等靈活的調用特性。

        服務治理方面:

        一、實現了集羣、容錯、負載均衡及路由策略

        二、實現了註冊功能,完成提供者、消費者註冊、訂閱通知策略等;

        三、對外提供了服務提供者、消費者配置信息、調用鏈、依賴關係的展示接口,並能夠對服務提權、降級,配置路由信息等針對服務的治理手段;

        四、開發了服務管理控制檯dubbo-admin,能夠在此查看服務相關注冊信息,對服務實施治理;

        五、開發了服務監控臺dubbo-monitor,可查看服務實時調用狀況,包括調用次數,調用時間,吞吐量等統計信息,實時查看服務的健康情況,做爲服務治理手段的依據。

 

        2、dubbo適用於什麼場景?

        一、業務中須要高吞吐量、複雜的RPC調用,有服務治理需求的場景;

        二、有輕量級微服務化需求的場景;

        下面引用dubbo用戶手冊的需求描述來講明什麼狀況下須要用到dubbo:

        

        在大規模服務化以前,應用可能只是經過 RMI 或 Hessian 等工具,簡單的暴露和引用遠程服務,經過配置服務的URL地址進行調用,經過 F5 等硬件進行負載均衡。

        當服務愈來愈多時,服務 URL 配置管理變得很是困難,F5 硬件負載均衡器的單點壓力也愈來愈大。 此時須要一個服務註冊中心,動態的註冊和發現服務,使服務的位置透明。並經過在消費方獲取服務提供方地址列表,實現軟負載均衡和 Failover,下降對 F5 硬件負載均衡器的依賴,也能減小部分紅本。

        當進一步發展,服務間依賴關係變得錯蹤複雜,甚至分不清哪一個應用要在哪一個應用以前啓動,架構師都不能完整的描述應用的架構關係。 這時,須要自動畫出應用間的依賴關係圖,以幫助架構師理清理關係。

        接着,服務的調用量愈來愈大,服務的容量問題就暴露出來,這個服務須要多少機器支撐?何時該加機器? 爲了解決這些問題,第一步,要將服務如今天天的調用量,響應時間,都統計出來,做爲容量規劃的參考指標。其次,要能夠動態調整權重,在線上,將某臺機器的權重一直加大,並在加大的過程當中記錄響應時間的變化,直到響應時間到達閥值,記錄此時的訪問量,再以此訪問量乘以機器數反推總容量。

        以上是 Dubbo 最基本的幾個需求。

 

        3、dubbo的整體架構是什麼樣的?

        調用關係說明:

        

        0、服務容器在啓動時啓動、加載服務提供者;

        一、啓動時,服務提供者向註冊中心註冊服務;

        二、啓動時,服務消費者向註冊中心訂閱服務;

        三、註冊中心給消費者返回服務提供者的地址列表,的提供者服務有什麼變更,將用長鏈接推送變更數據給訂閱者;

        四、服務消費者發起對提供者服務的調用,提供者返回調用結果給消費者;

        五、服務消費者和提供者在內存中累計調用次數和調用時間,每分鐘發送一次統計數據給監控中心Monitor,供監控中心統計查詢。

        Dubbo 架構具備如下幾個特色,分別是連通性、健壯性、伸縮性、以及向將來架構的升級性。

 

        整體設計:

        

        此圖在學習源碼前看的眼花繚亂,學習以後看一目瞭然。

        

        圖例說明:

  • 圖中左邊淡藍背景的爲服務消費方使用的接口,右邊淡綠色背景的爲服務提供方使用的接口,位於中軸線上的爲雙方都用到的接口。
  • 圖中從下至上分爲十層,各層均爲單向依賴,右邊的黑色箭頭表明層之間的依賴關係,每一層均可以剝離上層被複用,其中,Service 和 Config 層爲 API,其它各層均爲 SPI。
  • 圖中綠色小塊的爲擴展接口,藍色小塊爲實現類,圖中只顯示用於關聯各層的實現類。
  • 圖中藍色虛線爲初始化過程,即啓動時組裝鏈,紅色實線爲方法調用過程,即運行時調時鏈,紫色三角箭頭爲繼承,能夠把子類看做父類的同一個節點,線上的文字爲調用的方法。

        各層說明:

  • config 配置層:對外配置接口,以 ServiceConfigReferenceConfig 爲中心,能夠直接初始化配置類,也能夠經過 spring 解析配置生成配置類
  • proxy 服務代理層:服務接口透明代理,生成服務的客戶端 Stub 和服務器端 Skeleton, 以ServiceProxy 爲中心,擴展接口爲 ProxyFactory
  • registry 註冊中心層:封裝服務地址的註冊與發現,以服務 URL 爲中心,擴展接口爲RegistryFactoryRegistryRegistryService
  • cluster 路由層:封裝多個提供者的路由及負載均衡,並橋接註冊中心,以 Invoker 爲中心,擴展接口爲 ClusterDirectoryRouterLoadBalance
  • monitor 監控層:RPC 調用次數和調用時間監控,以 Statistics 爲中心,擴展接口爲MonitorFactoryMonitorMonitorService
  • protocol 遠程調用層:封將 RPC 調用,以 InvocationResult 爲中心,擴展接口爲 Protocol,InvokerExporter
  • exchange 信息交換層:封裝請求響應模式,同步轉異步,以 RequestResponse 爲中心,擴展接口爲 ExchangerExchangeChannelExchangeClientExchangeServer
  • transport 網絡傳輸層:抽象 mina 和 netty 爲統一接口,以 Message 爲中心,擴展接口爲 Channel,TransporterClientServerCodec
  • serialize 數據序列化層:可複用的一些工具,擴展接口爲 SerializationObjectInput,ObjectOutputThreadPool

 

        關係說明:

  • 在 RPC 中,Protocol 是核心層,也就是隻要有 Protocol + Invoker + Exporter 就能夠完成非透明的 RPC 調用,而後在 Invoker 的主過程上 Filter 攔截點。
  • 圖中的 Consumer 和 Provider 是抽象概念,只是想讓看圖者更直觀的瞭解哪些類分屬於客戶端與服務器端,不用 Client 和 Server 的緣由是 Dubbo 在不少場景下都使用 Provider, Consumer, Registry, Monitor 劃分邏輯拓普節點,保持統一律念。
  • 而 Cluster 是外圍概念,因此 Cluster 的目的是將多個 Invoker 假裝成一個 Invoker,這樣其它人只要關注 Protocol 層 Invoker 便可,加上 Cluster 或者去掉 Cluster 對其它層都不會形成影響,由於只有一個提供者時,是不須要 Cluster 的。
  • Proxy 層封裝了全部接口的透明化代理,而在其它層都以 Invoker 爲中心,只有到了暴露給用戶使用時,才用 Proxy 將 Invoker 轉成接口,或將接口實現轉成 Invoker,也就是去掉 Proxy 層 RPC 是能夠 Run 的,只是不那麼透明,不那麼看起來像調本地服務同樣調遠程服務。
  • 而 Remoting 實現是 Dubbo 協議的實現,若是你選擇 RMI 協議,整個 Remoting 都不會用上,Remoting 內部再劃爲 Transport 傳輸層和 Exchange 信息交換層,Transport 層只負責單向消息傳輸,是對 Mina, Netty, Grizzly 的抽象,它也能夠擴展 UDP 傳輸,而 Exchange 層是在傳輸層之上封裝了 Request-Response 語義。
  • Registry 和 Monitor 實際上不算一層,而是一個獨立的節點,只是爲了全局概覽,用層的方式畫在一塊兒。

        模塊分包:

     

 

        模塊說明:

  • dubbo-common公共邏輯模塊,提供了各類Util類,通用模塊。
  • dubbo-remoting遠程通信模塊,主要實現DubboProtocol底層通信細節(用RMI協議,此包沒用),包含的接口有:Transaction(傳輸層),Exchange數據交換層等;
  • dubbo-rpc遠程調用模塊,實現Protocol,Invoker, Exporter等上層協議接口定義,實現DubboProtocol協議的上層實現,以及DubboCodec類(dubbo編碼)實現;封裝了Hession協議、RMI協議、Http協議、WebService協議、Rest協議、Thrift等協議的實現;抽象了動態代理,只包含一對一的調用,不關心集羣的管理。
  • dubbo-cluster集羣模塊,將多個提供方假裝成一個服務方,定義了Cluster集羣接口、容錯接口、Loadbalance負載均衡接口、Route接口,Directry目錄接口,並提供了以上接口的各類實現。集羣的地址列表能夠是靜態配置的,也能夠是由註冊中心下發。
  • dubbo-register註冊中心模塊,基於註冊中心下發地址的集羣方式,以及對各類註冊中心的抽象。
  • dubbo-config配置模塊,實現服務提供者和消費者的配置定義加載。
  • dubbo-container容器模塊,實現了啓動時的服務提供者和消費者啓動、加載、初始化。一個 Standlone 的容器,以簡單的 Main 加載 Spring 啓動,由於服務一般不須要 Tomcat/JBoss 等 Web 容器的特性,不必用 Web 容器去加載服務。
  • dubbo-monitor 監控模塊:統計服務調用次數,調用時間的,調用鏈跟蹤的服務。

        總體上按照分層結構進行分包,與分層的不一樣點在於:

  • container 爲服務容器,用於部署運行服務,沒有在層中畫出。
  • protocol 層和 proxy 層都放在 rpc 模塊中,這兩層是 rpc 的核心,在不須要集羣也就是隻有一個提供者時,能夠只使用這兩層完成 rpc 調用。
  • transport 層和 exchange 層都放在 remoting 模塊中,爲 rpc 調用的通信基礎。
  • serialize 層放在 common 模塊中,以便更大程度複用。

        4、dubbo調用的過程是什麼樣的?

        調用鏈:

        展開總設計圖的紅色調用鏈,以下:

 

 

        暴露服務時序圖:

        展開總設計圖左邊服務提供方暴露服務的藍色初始化鏈,時序圖以下:

 

        引用服務時序圖:

        展開總設計圖右邊服務消費方引用服務的藍色初始化鏈,時序圖以下:

 

        注:以上大量引用了dubbo的develop手冊的文字和圖片內容。

相關文章
相關標籤/搜索