dubbo解析-集群容错顶层抽象类AbstractClusterInvoker详解

本文基于dubbo 2.7.5版本代码

集群容错顶层抽象类AbstractClusterInvoker详解


上一篇文章已经介绍了Cluster接口有10个实现类。每个Cluster实现类都会创建一个对应的Cluster Invoker对象。
MockClusterWrapper是包装类,ZoneAwareCluster在多个配置中心场景下使用,这两个类其他文章介绍。
其余的8个实现类及其对应的Cluster Invoker类如下:

ClusterCluster Invoker作用
FailoverClusterFailoverClusterInvoker
FailfastClusterFailfastClusterInvoker
FailsafeClusterFailsafeClusterInvoker
FailbackClusterFailbackClusterInvoker
ForkingClusterForkingClusterInvoker
AvailableClusterAvailableClusterInvoker
MergeableClusterMergeableClusterInvoker
BroadcastClusterBroadcastClusterInvoker

Cluster Invoker类都继承AbstractClusterInvoker类,实现了抽象方法doInvoke。

AbstractClusterInvoker

AbstractClusterInvoker实现了接口Invoker。构造方法入参必须有Directory对象。
Directory对象叫做服务目录,持有全部可用的远程服务提供者列表,客户端使用远程服务提供者访问远程服务。远程服务提供者也实现了Invoker接口,如果远程服务以dubbo协议提供,那么客户端通过Invoker接口的实现类DubboInvoker访问。Directory后面的文章在做介绍。
AbstractClusterInvoker类中最关键的方法是:

public Result invoke(final Invocation invocation) throws RpcException

客户端访问远程服务时,首先调用AbstractClusterInvoker的invoke方法。如下图:
invoke方法

  1. 访问Directory的list方法在介绍Directory的时候做说明。
  2. 访问子类的doInvoke方法在介绍子类的时候,做介绍。
  3. select方法首先处理sticky参数。sticky默认为false,当设置为true时,表示在调用远程服务时,尽量使用之前使用过的远程服务提供者。AbstractClusterInvoker用字段stickyInvoker记录最后一次访问的服务提供者,下次再访问同一个服务的方法时,会使用stickyInvoker记录的服务提供者。如果sticky为false或者stickyInvoker不可用,那么会调用doSelect方法筛选服务。下面的代码做了删减,只保留了关键部分:
private Invoker<T> doSelect(LoadBalance loadbalance, Invocation invocation,
                                List<Invoker<T>> invokers, List<Invoker<T>> selected) throws RpcException {
        Invoker<T> invoker = loadbalance.select(invokers, getUrl(), invocation);
        if ((selected != null && selected.contains(invoker))
                || (!invoker.isAvailable() && getUrl() != null && availablecheck)) {
                Invoker<T> rInvoker = reselect(loadbalance, invocation, invokers, selected, availablecheck);
                if (rInvoker != null) {
                    invoker = rInvoker;
                } else {
                    int index = invokers.indexOf(invoker);
                    invoker = invokers.get((index + 1) % invokers.size());
                }
        }
        return invoker;
    }

doSelect首先通过Loadbalance从服务列表选择一个服务。当服务调用重试时,selected不为null,其记录了重试使用过的服务,如果负载均衡筛选出的服务不可用或者重试已经调用过,那么会调用reselect方法重新筛选。
reselect方法使用Loadbalance对服务列表做两次筛选,第一次是对不在selected列表的其他服务筛选,如果筛选不出来,那么进行第二次筛选,第二次筛选是从所有可用的服务中使用Loadbalance筛选。
select方法的总体流程如下:
select方法
select方法还涉及到参数cluster.availablecheck,默认为true。如果为true,上图菱形块中都会检查服务是否可用;如果设置false,菱形块中服务可用性不再检查,直接认为服务不可用。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值