先來回憶一下, 一個rpc遠程服務調用, 我們通常是怎麼寫的:java
以http協議爲例, 咱們會封裝一個http協議的客戶端, 服務端多是直接用spring mvc編寫的restful服務spring
而後客戶端把服務的地址經過spring注入或者直接從配置文件裏讀取.緩存
整個調用過程以下圖服務器
Dubbo做爲遠程服務調用框架, 爲了能在各環節都能靈活擴展, 在不一樣協議上能將調用過程標準化,restful
須要考慮的問題可遠沒那麼簡單, 他將RPC過程進行了細化分解, 高度抽象網絡
下面是我在學習了dubbo源碼以後, 對幾個核心概念的理解:mvc
下面是根據dubbo服務調用過程, 大體整理出來的一個比較粗略的調用關係圖:負載均衡
下面是Dubbo官方文檔給出的說明, 將系統按功能分解爲幾個層次:框架
配置, 註冊中心, 路由,監控,序列化暫不關注.異步
來看看, 其餘每一層大體的類結構設計思路:
服務代理層:
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引用.
在protocol基類中, 會緩存暴露的及引用的invoker, 以便能統一對服務作管理, 好比destroy.
信息交換層(exchange):
下面是信息交換層的接口調用關係,
在服務端, 經過bind方法, 將一個服務url 綁定到一個消息處理方法.
在客戶端, 經過connect方法, 一樣把服務端返回的消息, 放到exchangeHandler中進行處理.
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的對接.