博客 / 詳情

返回

dubbo框架 - 服務消費者流程

1. 前言

在 Dubbo 框架中,服務消費者通過 XML 配置方式引用服務時,涉及多個模塊之間的協作。

不放dubbo官方的設計圖了,這裏同樣放一張自己畫的服務消費者調用圖,後面的介紹也是圍繞這張圖來的。

以下是服務消費者引用服務時,各個模塊之間的源碼方法調用關係的詳細説明。

2. 簡述過程

dubbo-config-spring 項目模塊中,dubbo 框架定義了 dubbo.xsd。業務使用時,可以基於 定義好的標籤(<dubbo:reference>等),在 xml 中配置要發佈的服務。

這部分內容可以查看前面寫的 《Spring XML自定義命名空間》。

服務提供者在啓動時,DubboNamespaceHandler 中會根據 XML 配置中的 <dubbo:reference> 標籤引用服務,整個過程大致如下:

  1. 解析 XML 配置

    • 解析 <dubbo:reference> 標籤,創建 ReferenceConfig 對象。
  2. 服務引用

    • 調用 ReferenceConfig.get() 方法,開始服務引用過程。
  3. 協議引用

    • ReferenceConfig.get() 方法內部調用 Protocol.refer() 方法,通過具體的協議實現服務的引用。
  4. 服務發現和負載均衡

    • 通過 RegistryDirectory 進行服務發現,並通過 ClusterLoadBalance 實現負載均衡。
  5. 代理創建

    • 使用 ProxyFactory 創建服務接口的代理對象。

3. ReferenceConfig 模塊

  • 作用:負責服務引用的配置和管理,是服務引用的入口。
  • 關鍵方法ReferenceConfig.get()
public class ReferenceConfig<T> {
    private volatile T ref;

    public synchronized T get() {
        if (ref == null) {
            init();
        }
        return ref;
    }

    private void init() {
        // 調用 Protocol.refer()
        Invoker<?> invoker = protocol.refer(interfaceClass, url);
        // 創建代理對象
        ref = proxyFactory.getProxy(invoker);
    }
}

4. Protocol 模塊

  • 作用:負責服務的導出和引用。
  • 關鍵方法Protocol.refer()
public interface Protocol {
    <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException;
}

5. RegistryProtocol.refer()

  • 作用:處理服務發現和引用相關的邏輯。
  • 調用關係

    1. 獲取註冊中心:通過 RegistryFactory 獲取 Registry 實例。
    2. 創建服務目錄:創建 RegistryDirectory,用於管理服務提供者的地址列表。
    3. 訂閲服務:通過 Registry 訂閲服務提供者信息。
    4. 集羣合併:通過 Cluster.join() 將多個服務提供者的 Invoker 合併為一個集羣 Invoker
public class RegistryProtocol implements Protocol {
    @Override
    public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
        // 1. 獲取註冊中心
        Registry registry = registryFactory.getRegistry(url);
        // 2. 創建服務目錄
        RegistryDirectory<T> directory = new RegistryDirectory<>(type, url);
        // 3. 訂閲服務提供者
        directory.setRegistry(registry);
        directory.subscribe(subscribeUrl);
        // 4. 返回集羣 Invoker
        return cluster.join(directory);
    }
}

6. Cluster 模塊

  • 作用:負責將多個服務提供者的 Invoker 合併為一個集羣 Invoker,實現負載均衡和容錯。
  • 關鍵方法Cluster.join()
public interface Cluster {
    <T> Invoker<T> join(Directory<T> directory) throws RpcException;
}

7. Invoker 模塊

  • 作用:表示一個可調用的服務引用,是服務調用的核心模型。
  • 關鍵方法Invoker.invoke() 用於執行遠程調用。
public interface Invoker<T> {
    Result invoke(Invocation invocation) throws RpcException;
}

8. ProxyFactory 模塊

  • 作用:負責創建服務接口的代理對象。
  • 關鍵方法ProxyFactory.getProxy()
public interface ProxyFactory {
    <T> T getProxy(Invoker<T> invoker) throws RpcException;
}

9. LoadBalance 模塊

  • 作用:提供負載均衡策略,選擇合適的 Invoker 進行調用。
  • 關鍵方法LoadBalance.select()
public interface LoadBalance {
    <T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException;
}

10. 總結

在 Dubbo 服務消費者的引用過程中,多個模塊協同工作:

  • ReferenceConfig:負責服務引用的配置和入口。
  • Protocol 和 Invoker:負責服務的引用和調用。
  • Registry 和 Directory:負責服務的發現和動態管理。
  • Cluster 和 LoadBalance:負責負載均衡和容錯。
  • ProxyFactory:負責創建服務接口的代理對象。
圖示化流程
ReferenceConfig.get() 
    └── RegistryProtocol.refer()
          └── Registry.getRegistry()
          └── RegistryDirectory.subscribe()
          └── Cluster.join()
                └── LoadBalance.select()
    └── ProxyFactory.getProxy()
  1. ReferenceConfig.get()

    • 解析服務引用配置,準備服務引用。
    • 調用 Protocol.refer() 進行服務引用。
  2. RegistryProtocol.refer()

    • 獲取註冊中心並創建服務目錄。
    • 訂閲服務提供者信息。
    • 通過 Cluster.join() 返回集羣 Invoker。
  3. Cluster.join()

    • 合併多個服務提供者的 Invoker,實現負載均衡。
  4. ProxyFactory.getProxy()

    • 創建服務接口的代理對象,供消費者使用。
  5. LoadBalance.select()

    • 在服務調用時,選擇合適的 Invoker 進行調用。
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.