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. 在这里插入图片描述
    调用合并器源码:
    在这里插入图片描述

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