1. 程式人生 > >Dubbo學習筆記5:Dubbo整體框架分析

Dubbo學習筆記5:Dubbo整體框架分析

什麽 資源 AD 文本文件 font ren factor exporter 服務提供者

Dubbo的分層架構

本文將簡單介紹Dubbo的分層架構設計,如下圖是Dubbo官方的整體架構圖:

技術分享圖片

Dubbo官方提供的該架構圖很復雜,一開始我們沒必要深入細節,下面我們簡單介紹下其中的主要模塊。

  • 其中Service和Config層為API,對於服務提供方來說,使用ServiceConfig API來代表一個要發布的服務配置對象,對於服務消費方來說,ReferenceConfig代表了一個要消費的服務的配置對象。可以直接初始化配置類,也可以通過Spring解析配置自動生成配置類。
  • 其他各層均為SPI層,SPI意味著下面各層都是組件化可以被替換的,這也是Dubbo設計的比較好的一點。Dubbo增強了JDK中提供的標準SPI功能,在Dubbo中除了Service和Config層外,其他各層都是通過實現擴展點接口來提供服務的,Dubbo增強的SPI增加了對擴展點IoC和AOP的支持,一個擴展點可以直接setter註入其他擴展點,並且不會一次性實例化擴展點的所有實現類,這避免了當擴展點實現類初始化很耗時,但當時還沒有用上它的功能時仍進行加載,浪費資源的情況;增強的SPI是在具體用某一個實現類的時候才對具體實現類進行實例化。後續會具體介紹Dubbo增強的SPI的實現原理。
  • proxy服務代理層:擴展接口為ProxyFactory,Dubbo提供的實現主要有JavassistProxyFactory(默認使用)和JdkProxyFactory,用來對服務提供方和服務消費方的服務進行代理。
  • registry註冊中心層:封裝服務地址的註冊與發現,擴展接口Registry對應的擴展接口實現為ZookeeperRegistry/RedisRegistry/MulticastRegistry/DubboRegistry等。擴展接口RegistryFactory對應的擴展接口實現為DubboRegistryFactory/DubboRegistryFactory/RedisRegistryFactory/ZookeeperRegistryFactory。
  • cluster路由層:封裝多個提供者的路由及負載引擎,並橋接註冊中心,集群容錯擴展接口Cluster對應的實現類有FailoverCluster(失敗重試)/FailbackCluster(失敗自動恢復)/FailfastCluster(快速失敗)/FailsafeCluster(失敗安全)/ForkingCluster(並行調用)等,均衡擴展接口LoadBalance對應的實現類為RandomLoadBalance(隨機)/RoundRobinLoadBalance(輪詢)/LeastActiveLoadBalance(最小活躍數)/ConsistentHashLoadBalance(一致性hash)等。
  • monitor監控層:RPC調用次數和調用時間監控,擴展接口為MonitorFactory,對應的實現類為DubboMonitorFactory。
  • protocol遠程調用層:封裝RPC調用,擴展接口為Protocol,對應實現有RegistryProtocol/DubboProtocol/InjvmProtocol等。
  • exchange信息交換層:封裝請求響應模式,同步轉異步,擴展接口Exchanger,對應擴展實現有HeaderExchanger等。
  • transport網絡傳輸層:抽象mina和netty為統一接口,擴展接口為Channel,對應實現有NettyChannel/MinaChannel等。
  • serialize數據序列化層:可復用的一些工具,擴展接口為Serialization,對應擴展實現有DubboSerialization/FastJsonSerialization/Hessian2Serialization/JavaSerialization等,擴展接口ThreadPool對應擴展實現有FixedThreadPool/CachedThreadPool/LimitedThreadPool等。

上面說了那麽多關於擴展點的東西,那麽具體什麽是擴展點呢,下面看下Dubbo擴展點一個簡單例子。以擴展點Protocol為例,如果我們想自己寫一個Protocol擴展接口的實現類,那麽我們想自己寫一個Protocol擴展接口的實現類,那麽我們需要在實現類所在的Jar包內的 METAINF/dubbo/ 目錄下創建一個名字為 com.alibaba.dubbo.rpc.Protocol 的文本文件,然後配置它的內容為:

myprotocol=com.alibaba.user.MyProtocol

假設該實現類MyProtocol的內容如下:

package com.alibaba.user;
import com.alibaba.dubbo.rpc.Protocol;
public class MyProtocol implements Protocol{
    // ...    
}

到此,可知我們需要實現Protocol接口。

那麽如何使用我們自定義的擴展實現呢?Dubbo配置模塊中,擴展點均有對應配置屬性或標簽,如下代碼通過配置指定使用哪個擴展實現:

<dubbo:protocol name="myprotocol" />

註意這裏的name必須與jar包內 METAINF/dubbo/ 目錄下 com.alibaba.dubbo.rpc.Protocol 文件中的名字一致。

遠程調用細節概述

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

技術分享圖片

  • 首先ServiceConfig類拿到對外提供服務的實際類ref(如:UserServiceImpl),然後通過ProxyFactory類的getInvoker方法使用ref生成一個AbstractProxyInvoker實例,到這一步就完成了具體服務到Invoker的轉化。接下來就是Invoker轉換為Exporter的過程。Dubbo處理服務暴露的關鍵就在Invoker轉換到Exporter的過程,上圖中的紅色部分。
  • Dubbo協議的Invoker轉為Exporter發生在DubboProtocol類的export方法中,它主要是創建一個Netty Server偵聽服務,並接收客戶端發來的各種請求,通訊細節由Dubbo自己實現,然後註冊服務到服務註冊中心。

服務消費者消費一個服務的詳細過程

技術分享圖片

  • 首先ReferenceConfig類的init方法調用Protocol的refer方法生成Invoker實例(如上圖的紅色部分),這是服務消費的關鍵。接下來把Invoker轉換為客戶端需要的接口(如:UserServiceBo)。
  • Dubbo協議的Invoker轉換為客戶端需要的接口,發生在DubboProtocol的refer方法中,它主要創建一個 netty client鏈接服務提供者,通訊細節由Dubbo自己實現。

Dubbo學習筆記5:Dubbo整體框架分析