1. 前言
在 Dubbo 框架中,服務提供者通過 XML 配置發佈服務時,涉及多個模塊之間的協作,包括 ServiceConfig、Protocol、Exporter、Registry、Exchange 和 Transport 等。
1、官網代碼設計圖
這是官網代碼架構設計圖,主要體現各個模塊之間的調用關係。
不僅包含服務提供者調用關係,也包含服務消費者的,具體解釋看官網介紹。
為了便於理解,在自己閲讀源碼後,我又畫了張專門提醒服務提供者的設計圖,後面的介紹也是圍繞這張圖來的。
2. 服務提供者設計圖
以下是這些模塊之間的源碼方法調用關係以及服務提供者發佈服務的全過程詳細説明。
2. 簡述過程
在 dubbo-config-spring 項目模塊中,dubbo 框架定義了 dubbo.xsd。業務使用時,可以基於 定義好的標籤(<dubbo:service>等),在 xml 中配置要發佈的服務。
這部分內容可以查看前面寫的 《Spring XML自定義命名空間》。
服務提供者在啓動時,DubboNamespaceHandler 中會根據 XML 配置中的 <dubbo:service> 標籤發佈服務,整個過程大致如下:
-
解析 XML 配置:
- 解析
<dubbo:service>標籤,創建ServiceConfig對象。
- 解析
-
服務導出:
- 調用
ServiceConfig.export()方法,開始服務導出過程。
- 調用
-
協議導出:
ServiceConfig.export()方法內部調用Protocol.export()方法,通過具體的協議實現服務的導出。
-
註冊服務:
- 將服務註冊到註冊中心。
3. ServiceConfig 模塊
- 作用:負責服務配置的解析和管理,是服務導出的入口。
- 關鍵方法:
ServiceConfig.export()
public class ServiceConfig<T> {
public synchronized void export() {
// 檢查配置並準備導出
if (!shouldExport()) {
return;
}
// 導出服務
doExport();
}
private void doExport() {
// 調用 Protocol.export()
Invoker<?> invoker = createInvoker();
Exporter<?> exporter = protocol.export(invoker);
exporters.add(exporter);
}
}
3. Protocol 模塊
- 作用:負責服務的導出和引用。不同的協議(如 Dubbo、HTTP 等)有不同的實現。
- 關鍵方法:
Protocol.export()
public interface Protocol {
<T> Exporter<T> export(Invoker<T> invoker) throws RpcException;
}
5. RegistryProtocol.export()
- 作用:處理服務註冊相關的邏輯,將服務註冊到註冊中心。
-
調用關係:
- 實際服務導出:調用內部協議(如
DubboProtocol)進行服務的實際導出。 - 服務註冊:通過
Registry將服務註冊到註冊中心。 - 返回 Exporter:創建並返回一個
Exporter對象,用於管理服務的生命週期。
- 實際服務導出:調用內部協議(如
public class RegistryProtocol implements Protocol {
@Override
public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
// 1. 實際服務導出
Exporter<T> exporter = protocol.export(invoker);
// 2. 註冊服務到註冊中心
Registry registry = registryFactory.getRegistry(invoker.getUrl());
registry.register(invoker.getUrl());
// 3. 返回 Exporter
return exporter;
}
}
6. DubboProtocol.export()
- 作用:通過 Dubbo 協議導出服務。
-
調用關係:
- 創建一個
DubboExporter實例。 - 啓動服務器,監聽服務請求。
- 創建一個
public class DubboProtocol implements Protocol {
@Override
public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
// 創建 DubboExporter 實例
DubboExporter<T> exporter = new DubboExporter<>(invoker, ...);
// 啓動服務器,監聽端口
openServer(invoker.getUrl());
return exporter;
}
}
7. Transport 和 Exchange 模塊
-
Transport 模塊:
- 作用:負責底層的網絡傳輸,綁定服務端口。
- 關鍵方法:
Transporter.bind()用於綁定服務器。
-
Exchange 模塊:
- 作用:提供請求-響應模型,負責信息交換。
- 關鍵方法:
ExchangeServer用於處理請求。
8. 總結
在 Dubbo 服務提供者的發佈過程中,多個模塊協同工作:
- ServiceConfig:負責服務配置和導出的入口。
- Protocol 和 Exporter:負責服務的導出和生命週期管理。
- Registry:負責服務的註冊和發現。
- Transport 和 Exchange:負責底層的網絡通信和信息交換。
圖示化流程
ServiceConfig.export()
└── RegistryProtocol.export()
└── DubboProtocol.export()
└── Transporter.bind() (綁定端口)
└── ExchangeServer (啓動並監聽)
└── Registry.register() (註冊服務)
-
ServiceConfig.export():
- 解析服務配置,準備服務導出。
- 調用
Protocol.export()進行服務導出。
-
RegistryProtocol.export():
- 調用
DubboProtocol.export()進行服務的實際導出。 - 將服務註冊到註冊中心。
- 調用
-
DubboProtocol.export():
- 創建
Exporter實例。 - 啓動服務器,監聽服務請求。
- 創建
-
Transport 和 Exchange:
- 通過
Transporter.bind()和ExchangeServer啓動網絡服務。
- 通過