Dubbo的核心概念

 

先來回憶一下, 一個rpc遠程服務調用, 我們通常是怎麼寫的:java

以http協議爲例, 咱們會封裝一個http協議的客戶端, 服務端多是直接用spring mvc編寫的restful服務spring

而後客戶端把服務的地址經過spring注入或者直接從配置文件裏讀取.緩存

整個調用過程以下圖服務器

clip_image001

Dubbo做爲遠程服務調用框架, 爲了能在各環節都能靈活擴展, 在不一樣協議上能將調用過程標準化,restful

須要考慮的問題可遠沒那麼簡單, 他將RPC過程進行了細化分解, 高度抽象網絡

下面是我在學習了dubbo源碼以後, 對幾個核心概念的理解:mvc

  • 基本的, 定義客戶端 服務端接口 Client, Server
  • 爲了兼容不一樣的協議, 對不一樣協議的網絡傳輸調用, 抽象出Transporter接口, 綁定服務url與處理回調方法. 對上層屏蔽底層不一樣協議處理方法.
  • 因爲不一樣協議的交互數據, 行爲不一致, 在傳輸層上, 又抽象了一層信息交互層(exchanger), 對上層提供了一致的消息傳遞處理方法, 一致的入參(Request), 回參(Response),消息回調方法(ExchangeHandler).
  • 爲了進一步簡化遠程服務調用, 屏蔽調用處理細節, 使可以像調用本地方法同樣調用遠程服務. 也出於服務註冊發現管理的須要, 又抽象出了一層Protocol層, 官方稱之爲遠程調用層, 將調用方法,調用參數,參數類型封裝到Invocation, 將結果封裝到Result對象中, 返回給上層調用.對Protocol的調用上層來講, protocol接口核心主要作了兩件事:暴露服務以及得到遠程服務的引用
  • Invoker是Dubbo對方法的抽象, 在服務端, exporter經過protocol, 將invoker暴露出來.在客戶端, 經過protocol得到一個遠程服務引用, 封裝爲invoker給上層調用.
  • 再往上, 在業務層的業務bean, 若是要像調用本地方法同樣調用服務, 不可能直接調用invoker吧, 因而中間還有一層代理層, 代理層將invoker轉換成實現了業務服務接口的代理實例.
  • 爲了能在服務調用過程當中, 補充其餘功能, 諸如記錄日誌, 權限控制,添加緩存,參數校驗等, 使用過濾器模式對invoker進行處理返回.

下面是根據dubbo服務調用過程, 大體整理出來的一個比較粗略的調用關係圖:負載均衡

clip_image002

 

下面是Dubbo官方文檔給出的說明, 將系統按功能分解爲幾個層次:框架

  • config,配置層,對外配置接口,以ServiceConfig, ReferenceConfig爲中心,能夠直接new配置類,也能夠經過spring解析配置生成配置類
  • proxy,服務代理層,服務接口透明代理,生成服務的客戶端Stub和服務器端Skeleton,以ServiceProxy爲中心,擴展接口爲ProxyFactory
  • registry,註冊中心層,封裝服務地址的註冊與發現,以服務URL爲中心,擴展接口爲RegistryFactory, Registry, RegistryService
  • cluster,路由層,封裝多個提供者的路由及負載均衡,並橋接註冊中心,以Invoker爲中心,擴展接口爲Cluster, Directory, Router, LoadBalance
  • monitor,監控層,RPC調用次數和調用時間監控,以Statistics爲中心,擴展接口爲MonitorFactory, Monitor, MonitorService
  • protocol,遠程調用層,封將RPC調用,以Invocation, Result爲中心,擴展接口爲Protocol, Invoker, Exporter
  • exchange,信息交換層,封裝請求響應模式,同步轉異步,以Request, Response爲中心,擴展接口爲Exchanger, ExchangeChannel, ExchangeClient, ExchangeServer
  • transport,網絡傳輸層,抽象mina和netty爲統一接口,以Message爲中心,擴展接口爲Channel, Transporter, Client, Server, Codec
  • serialize,數據序列化層,可複用的一些工具,擴展接口爲Serialization, ObjectInput, ObjectOutput, ThreadPool

配置, 註冊中心, 路由,監控,序列化暫不關注.異步

來看看, 其餘每一層大體的類結構設計思路:

服務代理層:

image

ServiceConfig, ReferenceConfig 等須要獲取invoker實例, 或者須要將invoker轉成對應的代理的時候, 都能看到ProxyFactory的影子.

如在ServiceConfig中, 經過代理得到invoker, 並暴露服務.

Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, url);

 Exporter<?> exporter = protocol.export(invoker);

在ReferenceConfig中, 經過代理得到invoker對應的服務實例

private T createProxy(Map<String, String> map) {
 ……

// 建立服務代理
 return (T) proxyFactory.getProxy(invoker);
}
 

遠程調用層(Protocol):

下面是Protocol層的幾個核心接口, 能夠看到Protocol接口主要負責將invoker包裝爲exporter對外發布,

同時也支持將遠程服務url封裝爲invoker引用.

image

在protocol基類中, 會緩存暴露的及引用的invoker, 以便能統一對服務作管理, 好比destroy.

 

信息交換層(exchange):

下面是信息交換層的接口調用關係,

在服務端, 經過bind方法, 將一個服務url 綁定到一個消息處理方法.

在客戶端, 經過connect方法, 一樣把服務端返回的消息, 放到exchangeHandler中進行處理.

 

image

ExchangeHandler只有一個接口方法: reply, 從channel接收到request請求處理以後返回結果.

入參request是Request類型參數, 返回參數Object是Response類型, 在DecodeHandler中, 進行Request, Response類型的封裝,解析.

public class HeaderExchanger implements Exchanger { 

 public static final String NAME = "header"; 

 public ExchangeClient connect(URL url, ExchangeHandler handler) throws RemotingException { 

 return new HeaderExchangeClient(Transporters.connect(url, new DecodeHandler(new HeaderExchangeHandler(handler)))); 

 } 

 public ExchangeServer bind(URL url, ExchangeHandler handler) throws RemotingException { 

 return new HeaderExchangeServer(Transporters.bind(url, new DecodeHandler(new HeaderExchangeHandler(handler)))); 

 } 

 }

從DubboProtocol中ExchangeHandler能夠看出, exchangeChannel能夠獲得invoker信息, 並從protocol中緩存的exporterMap裏找到invoker引用.

網絡傳輸層(transport):

Transporter有MinaTransporter, NettyTransporter等實現, 對不一樣協議的Server, Client作了封裝:

public class MinaTransporter implements Transporter {
    
    public static final String NAME = "mina";

    public Server bind(URL url, ChannelHandler handler) throws RemotingException {
        return new MinaServer(url, handler);
    }

    public Client connect(URL url, ChannelHandler handler) throws RemotingException {
        return new MinaClient(url, handler);
    }

}

以Netty爲例, SimpleChannelHanlder是Netty自帶的默認channel處理器, Dubbo設計了一個NettyHandler實現了dubbo的channelHandler與Netty channelHandler的對接.

相關文章
相關標籤/搜索