Dubbo——Merger的實現

Merger的實現

當一個接口有多種實現,消費者又需要同時引用不同的實現時,可以用group 來區分不同的實現,如下所示。

<dubbo:service group=" group1" interface=" com.xxx.testService" />
<dubbo:service group="group2" interface=" com.xxx.testService" />

如果我們需要並行調用不同group 的服務,並且要把結果集合並起來,則需要用到Merger特性。Merger實現了多個服務調用後結果合併的邏輯。雖然業務層可以自行實現這個能力,但Dubo直接封裝到框架中,作爲一種擴展點能力,簡化了業務開發的複雜度。Merger 的工作方式如圖所示:

在這裏插入圖片描述

框架中會有一些默認的合併實現。Merger接口上有@SPI註解,沒有默認值,屬於SPI擴展點。用戶可以基於Merger擴展點接口實現自己的自定義類型合併器。

總體結構

MergerCluster也是Cluster接口的一種實現,因此也遵循Cluter的設計模式,在invoker方法中完成具體邏輯。整個過程會使用merger接口的具體實現來合併結果集。在使用的時候,通過MergerFactory獲得各種具體的Merger實現。

Merger的12中默認實現的關係:
在這裏插入圖片描述
如果開啓了Merger特性,並且未指定合併器(Merger 的具體實現),則框架會根據接口的返回類型自動匹配合並器。我們可以擴展屬於自己的合併器,MergerFactory 在加載具體實現的時候,會用ExtensionLoader把所有SPI的實現都加載到緩存中。後續使用時直接從緩存中讀取,如果讀不到則會重新全量加載一次SPI.。內置的合併我們可以分爲四類: Array、Set、List、Map,實現都比較簡單,我們只列舉MapMerger的實現,如代碼所示:

在這裏插入圖片描述
整體思路就是,在Merger中新建一個Map,把返回的多個Map合併成一個。其他類型的合併器實現都是類似,因此不再贅述。

MergeableClusterInvoker機制

MergeableClusterInvoker串起了整個合併器邏輯。在瞭解MergeableClusterInvoker的機制之前,先回顧一下整個調用的過程:MergeableCuster#joion方法中直接生成並返回了MergeableCusterInvoker,MergeableClusterInvoker#invke方法又通過MergerFactory工廠獲取不同的Merger接口實現,完成了合併的具體邏輯。

MergeableCluster並沒有繼承抽象的Cluster實現,而是獨立完成了自己的邏輯。因此,它的整個邏輯和之前的Failover等機制不同,其步驟如下:

  1. 前置準備。通過directory獲取所有Invoker列表。

  2. 集羣器初步判斷某個方法是否有合併器,如果沒有,則不會並行調用多個group,找到第一個可以調用的Invoker直接調用就返回了。如果有合井器,則進入第3步。

  3. 獲取接口的返回類型。通過反射獲得返回類型,後續要根據這個返回值查找不同的合併器。

  4. 並行調用。把Invoker的調用封裝成一個個 Callable對象,放到線程池中執行,保存線程池返回的future對象到HashMap中,用於等待後續結果返回。

  5. 等待future 對象的返回結果。獲取配置的超時參數,遍歷(4)中得到的future對象,設置Future#get的超時時間,同步等待得到並行調用的結果。異常的結果會被忽略,正常的結果會被保存到list 中。如果最終沒有返回結果,則直接返回一個空的RpcResult:如果只有一個結果,那麼也直接返回,不需要再做合併;如果返回類型是void,則說明沒有返回值,也直接返回。

  6. 合併結果集。如果配置的是merger=".addAll",則直接通過反射調用返回類型中的addAll方法合併結果集。例如:返回類型是Set,則調用Set.addAll來合併結果,如代碼所示:

  7. 在這裏插入圖片描述
    調用合併器源碼:
    在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章