日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關咨詢
選擇下列產品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關閉右側工具欄

新聞中心

這里有您想知道的互聯網營銷解決方案
Dubbo的Remoting模塊解析

1 Dubbo 整體架構設計

dubbo-remoting 模塊提供多種客戶端和服務端通信功能。最底層部分即為 Remoting 層:

包括 Exchange、Transport和Serialize 三層。本文主要描述 Exchange 和 Transport 兩層。

Dubbo直接集成已有的第三方網絡庫,如Netty、Mina、Grizzly 等 NIO 框架:

dubbo-remoting-zookeeper使用 Apache Curator 實現與 zk 的交互。

2 dubbo-remoting-api

是其他 dubbo-remoting-* 模塊的頂層抽象,其他 dubbo-remoting 子模塊都是依賴第三方 NIO 庫,來實現 dubbo-remoting-api 模塊。

2.1 buffer 包

定義Buffer相關接口、抽象類及實現類。在各 NIO 框架中都有自己的緩沖區(qū)實現。但這里的 buffer 包在更高層面,抽象各個 NIO 框架的緩沖區(qū),同時也提供一些基礎實現。

2.2 exchange包

抽象 Request、Response,并為其添加很多特性。整個遠程調用的核心部分。

2.3 transport包

抽象網絡傳輸層,但只負責抽象單向消息傳輸,即:

  • ? 請求消息由 Client 端發(fā)出,Server 端接收
  • ? 響應消息由 Server 端發(fā)出,Client端接收

很多網絡庫可實現網絡傳輸,如Netty,transport包是在網絡庫上層的一層抽象。

2 傳輸層核心接口

“端點(Endpoint)”:一個 ip? 和 port? 唯一確定,兩端點間會創(chuàng)建 TCP 連接,雙向傳輸數據。

Dubbo 將 Endpoint 之間的 TCP 連接抽象為(Channel)通道:

  • ? 發(fā)起請求的 Endpoint 抽象為Client
  • ? 接收請求的 Endpoint 抽象為Server

2.1 Endpoint 接口

  • getXXX() 用于獲得 Endpoint 本身的一些屬性,如Endpoint 的本地地址、關聯的 URL 信息及底層 Channel 關聯的 ChannelHandler
  •  send() 負責數據發(fā)送
  •  close() 及 startClose() 用于關閉底層 Channel
  •  isClosed() 方法用于檢測底層 Channel 是否已關閉

3 Channel

對 Endpoint 雙方連接的抽象,就像傳輸管道。消息發(fā)送端往 Channel 寫入消息,接收端從 Channel 讀取消息。

3.1 接口定義

繼承 Endpoint 接口,也具備開關狀態(tài)以及發(fā)送數據能力??稍?Channel 上附加 KV 屬性:

4 ChannelHandler

注冊在 Channel 上的消息處理器

4.1 定義

@SPI 注解表明該接口是一個擴展點。

有一類特殊的 ChannelHandler 專門負責實現編解碼功能,實現:

  • 字節(jié)數據與有意義的消息之間的轉換
  • 或消息之間的相互轉換

該接口也是個擴展接口,encode()、decode() 被 @Adaptive 注解修飾,也就會生成適配器類,其中會根據 URL 中的 codec 值確定具體的擴展實現類。

DecodeResult 枚舉是在處理 TCP 傳輸時粘包和拆包使用的,如當前能讀取到的數據不足以構成一個消息時,就使用 NEED_MORE_INPUT 。

5 Client、RemotingServer

分別抽象客戶端、服務端,都繼承 Channel、Resetable 等接口,即都具備讀寫數據的能力。

都繼承了 Endpoint,只是在語義上區(qū)分請求和響應職責,都具備發(fā)送數據能力。

Client V.S Server

  •  Client 只能關聯一個 Channel
  • Server 可接收多個 Client 發(fā)起的 Channel 連接,所以在 RemotingServer 接口中定義查詢 Channel 的相關方法

6 Transporter

Dubbo 在 Client、Server 之上又封裝一層Transporter 接口:

@SPI 注解擴展接口,默認使用“netty”擴展名。

@Adaptive 注解表示動態(tài)生成適配器類:

  • 先后根據“server”“transporter”的值,確定 RemotingServer 的擴展實現類
  • 先后根據“client”“transporter”的值,確定 Client 接口的擴展實現

幾乎對每個支持的 NIO 庫,都有接口實現:

7.1 為何單獨抽象Transporter層,不直接讓上層使用 Netty?

利用依賴倒置原則,Netty、Mina、Grizzly 等 NIO 庫對外接口和使用方式不同,若在上層直接依賴 Netty 或Grizzly,就依賴具體 NIO 庫,而非依賴一個有傳輸能力的抽象,后續(xù)要切換實現,就需修改依賴和接入的相關代碼。

而有了 Transporter 層,就可通過 Dubbo SPI,修改使用的具體 Transporter 擴展實現,切換到不同 Client 和 RemotingServer 實現,切換底層 NIO 庫,而無須修改代碼。當有更先進的 NIO 庫出現,也只需開發(fā)相應的 dubbo-remoting-* 實現模塊提供 Transporter、Client、RemotingServer 等核心接口的實現,即可接入,完全符合開放封閉原則。

7 Transporters

不是一個接口,而是門面類,封裝:

  •  Transporter 對象的創(chuàng)建(通過 Dubbo SPI)
  • 及 ChannelHandler 的處理
public class Transporters {
private Transporters() {
...


public static RemotingServer bind(URL url,
ChannelHandler... handlers) throws RemotingException {
ChannelHandler handler;
if (handlers.length == 1) {
handler = handlers[0];
} else {
handler = new ChannelHandlerDispatcher(handlers);
}
return getTransporter().bind(url, handler);
}



public static Client connect(URL url, ChannelHandler... handlers)
throws RemotingException {
ChannelHandler handler;
if (handlers == null || handlers.length == 0) {
handler = new ChannelHandlerAdapter();
} else if (handlers.length == 1) {
handler = handlers[0];
} else { // ChannelHandlerDispatcher
handler = new ChannelHandlerDispatcher(handlers);
}
return getTransporter().connect(url, handler);
}



public static Transporter getTransporter() {
// 自動生成Transporter適配器并加載
return ExtensionLoader.getExtensionLoader(Transporter.class)
.getAdaptiveExtension();
}
}

在創(chuàng)建 Client、RemotingServer 時,可指定多個 ChannelHandler 綁定到 Channel,來處理其中傳輸的數據。Transporters.connect()、bind() 方法都會將多個 ChannelHandler 封裝成一個 ChannelHandlerDispatcher 對象。

ChannelHandlerDispatcher 也是 ChannelHandler 接口實現類之一,維護一個 CopyOnWriteArraySet 集,它所有的 ChannelHandler 接口實現都會調用其中每個 ChannelHandler 元素的相應方法。ChannelHandlerDispatcher 還提供增刪該 ChannelHandler 集合的相關方法。

8 總結

  • ? Endpoint 接口抽象“端點”概念,這是所有抽象接口的基礎
  • ? 上層使用方會通過 Transporters 門面類,獲取到 Transporter 的具體擴展實現,然后通過 Transporter 拿到相應 Client、RemotingServer 實現,就能建立(或接收)Channel 與遠端進行交互
  • ? 無論 Client、RemotingServer,都會使用 ChannelHandler 處理 Channel 中傳輸的數據,其中負責編解碼的 ChannelHandler 被抽象出為 Codec2 接口。

Transporter 層整體結構圖

參考: ??https://dubbo.apache.org/en-us/docs/dev/design.html??

本文轉載自微信公眾號「JavaEdge」,可以通過以下二維碼關注。轉載本文請聯系JavaEdge公眾號。


名稱欄目:Dubbo的Remoting模塊解析
路徑分享:http://m.5511xx.com/article/ccdepic.html