擴充性

擴充設計理念

可擴充性是任何系統追求的目標,它同樣適用於 Dubbo。

什麼是可擴充性

可擴充性是一種設計理念,代表著我們對未來的展望。我們希望基於現有的架構或設計,當未來某些方面發生變化時,我們可以用最小的變更來適應這種變化。

可擴充性的優點

可擴充性的優點主要體現在模組之間的解耦,符合開閉原則,即對擴充開放,對修改關閉。當系統新增一個新功能時,無需修改現有系統的結構和程式碼,只需新增一個擴充即可。

擴充實現

一般來說,系統會使用 Factory、IoC、OSGI 等來管理擴充(外掛)的生命週期。考慮到 Dubbo 的適用性,我不希望強依賴於 Spring 等 IoC 容器。而自己構建一個小的 IoC 容器又感覺有點過度設計,所以選擇最簡單的 Factory 方式來管理擴充(外掛)。在 Dubbo 中,所有內部和第三方實現都是平等的。

Dubbo 中的可擴充性

  • 平等對待第三方實現。在 Dubbo 中,所有內部實現和第三方實現都是平等的,使用者可以根據自身業務需求替換 Dubbo 提供的原生實現。
  • 每個擴充點只封裝一個變化因素,以最大程度地提高重用性。每個擴充點的實現者往往只關心一件事情。如果使用者需要擴充,只需要擴充他們關心的擴充點即可,這大大減少了使用者的工作量。

Dubbo 擴充的特性

Dubbo 中的擴充能力是從 JDK 標準 SPI 擴充點發現機制增強而來的,它改進了 JDK 標準 SPI 的以下問題

  • JDK 標準 SPI 會一次性初始化擴充點的所有實現。如果有一個擴充實現,初始化會需要時間,但如果沒有用到,也會被載入,這會浪費資源。
  • 如果擴充點載入失敗,甚至無法取得擴充點的名稱。例如:JDK 標準的 ScriptEngine,透過 getName() 取得腳本類型名稱,但如果因為缺少 jruby 而導致 RubyScriptEngine 類別載入失敗時,當使用者執行 ruby 腳本時,會回報 ruby 不支援,而不是真正的失敗原因。

基於 Dubbo 提供的擴充能力,使用者可以根據自身需求,輕鬆擴充其他協議、過濾器、路由等。以下介紹 Dubbo 擴充能力的特性。

  • 按需載入。Dubbo 的擴充能力並非一次性將所有實現都實例化,而是用到哪個擴充類別就實例化哪個,減少資源浪費。
  • 增加擴充類別的 IOC 能力。Dubbo 的擴充能力不只是發現擴充服務的實現類別,而是在此基礎上更進一步,如果擴充類別的屬性依賴於其他物件,Dubbo 會自動完成依賴物件的注入功能。
  • 增加擴充類別的 AOP 能力。Dubbo 的擴充能力會自動發現擴充類別的包裝類別,完成包裝類別的建構,增強擴充類別的功能。
  • 具備動態選擇擴充實現的能力。Dubbo 擴充會根據參數在運行時動態選擇對應的擴充類別,提高了 Dubbo 的擴充性。
  • 擴充實現可排序。可以根據使用者需求指定擴充實現的執行順序。
  • 提供擴充點的 Adaptive 能力。此能力讓部分擴充類別在消費者端生效,部分擴充類別在提供者端生效。

從 Dubbo 擴充的設計目標來看,Dubbo 實現的某些特性,例如擴充實現的動態選擇、IOC、AOP 等,都能夠為使用者提供非常靈活的擴充能力。

Dubbo 擴充載入流程

Dubbo 載入擴充的整個流程如下

//imgs/v3/concepts/extension-load.png

主要有 4 個步驟

  • 讀取並解析設定檔
  • 快取所有擴充實現
  • 根據使用者執行的擴充名稱,實例化對應的擴充實現
  • 執行擴充實例屬性的 IOC 注入,並實例化擴充包裝類別,實現 AOP 特性

如何使用 Dubbo 的擴充能力進行擴充

以下以擴充協議為例,說明如何使用 Dubbo 提供的擴充能力擴充 Triple 協議。

(1) 在協議實現 jar 包中放置一個文字檔:META-INF/dubbo/org.apache.dubbo.remoting.api.WireProtocol

tri=org.apache.dubbo.rpc.protocol.tri.TripleHttp2Protocol

(2) 實現類別內容

@Activate
public class TripleHttp2Protocol extends Http2WireProtocol {
     //...
}

說明:Http2WireProtocol 實現了 WireProtocol 介面

(3) 在 Dubbo 設定模組中,每個擴充點都有對應的設定屬性或標籤,設定中指定使用哪個擴充。例如

<dubbo:protocol name="tri" />

從以上擴充步驟可以看出,使用者基本是在黑箱下完成擴充。

Dubbo 擴充應用

Dubbo 的擴充能力非常靈活,在其自身功能的實現中無處不在。

//imgs/v3/concepts/extension-use.png

Dubbo 的擴充性讓 Dubbo 專案可以很容易地被拆分成一個一個的子模組,實現熱插拔特性。使用者可以完全根據自身需求,替換 Dubbo 原生的實現,以滿足自身的業務需求。

使用場景

  • 如果需要自訂負載平衡策略,可以使用 Dubbo 的擴充能力。
  • 如果需要實現自訂的註冊中心,可以使用 Dubbo 的擴充能力。
  • 如果需要實現自訂的過濾器,可以使用 Dubbo 的擴充能力。

Dubbo 擴展機制對內部實現和第三方實現一視同仁。更多使用場景,請參考 SPI 擴展實現


最後修改日期:2023 年 1 月 2 日:增強英文文檔 (#1798) (95a9f4f6c1c)