深度解析dubbo集群之API

本文基于dubbo v2.6.x

1. Cluster接口

我们在讲解服务引用com.alibaba.dubbo.registry.integration.RegistryProtocol#doRefer方法中有这么一段代码Invoker invoker = cluster.join(directory);根据RegistryDirectory对象生成invoker(如果有不太清楚的小伙伴可以回头看看本系列关于服务引用的文章《深度解析dubbo源码系列》),其中cluster 对象是通过dubbo spi注入进来的,同时Cluster也是个spi接口,我们看下它的定义:

@SPI(FailoverCluster.NAME)  //默认是failover 失败重试
public interface Cluster {

    /**
     * Merge the directory invokers to a virtual invoker.
     * 基于Directory 对象创建invoker对象
     * @param <T>
     * @param directory
     * @return cluster invoker
     * @throws RpcException
     */
    @Adaptive  //基于 Dubbo SPI Adaptive 机制,加载对应的 Cluster 实现,使用 URL.cluster 属性
    <T> Invoker<T> join(Directory<T> directory) throws RpcException;

}

我们看到它就一个join方法,然后返回值是一个invoker。默认的实现是FailoverCluster , 我们再来看下它的实现类们。
在这里插入图片描述
在这些实现类中都创建了与其功能相对应的invoker。
接下来我们分别介绍其功能与源码:

2. Cluster实现类讲解

2.1 FailoverCluster

Cluster默认实现,如果你没有配置cluster属性值,则默认使用该实现类,该实现类主要创建了对应的失败重试的invoker,我们一起来看下源码:

public class FailoverCluster implements Cluster {
    public final static String NAME = "failover";
    // 实现接口join方法 ,创建 对应invoker处理
    @Override
    public <T> Invoker<T> join(Directory<T> directory) throws RpcException {
        return new FailoverClusterInvoker<T>(directory); /// new 一个失败重试的invoker
    }
}

我们看到其源码很简单,就是创建了一个FailoverClusterInvoker 失败重试的invoker返回。

2.2 AvailableCluster

关于AvailableCluster 类我们可以从源码中看到它其实就是创建了一个AbstractClusterInvoker 实现类返回,在这个实现类中实现doInvoke 方法,该方法在服务调用的时候会执行,可以看出就是从众多服务提供者中选择一个可用的调用返回。由此我们可以总结出AvailableCluster 主要是能够保证调用的服务提供者可用。

public class AvailableCluster implements Cluster {
    public static final String NAME = "available";
    @Override
    public <T> Invoker<T> join(Directory<T> directory) throws RpcException {
        return new AbstractClusterInvoker<T>(directory) {
            @Override
            public Result doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException {
            	// 遍历 服务提供者invoker列表
                for (Invoker<T> invoker : invokers) {
                    if (invoker.isAvailable()) {// 是否可用
                        return invoker.invoke(invocation); // 调用
                    }
                }
                throw new RpcException("No provider available in " + invokers);
            }
        };

    }
}

2.3 BroadcastCluster

BroadcastCluster 集群类型主要是创建一个使用广播方式调用的invoker返回,我们可以看下源码:

public class BroadcastCluster implements Cluster {
    @Override
    public <T> Invoker<T> join(Directory<T> directory) throws RpcException {
    	// 创建广播调用方式的invoker
        return new BroadcastClusterInvoker<T>(directory);
    }

}

2.4 FailbackCluster

该FailbackCluster 实现主要创建一个 带有 调用失败,然后使用定时任务重试 功能的invoker,这个特别适用于送达通知。

public class FailbackCluster implements Cluster {

    public final static String NAME = "failback";

    @Override
    public <T> Invoker<T> join(Directory<T> directory) throws RpcException {
        return new FailbackClusterInvoker<T>(directory);
    }
}

2.5 FailfastCluster

该FailfastCluster 实现主要是创建一个带有快速失败功能的invoker,其实从class 名字上也能看出来,看下源码:

public class FailfastCluster implements Cluster {

    public final static String NAME = "failfast";

    @Override
    public <T> Invoker<T> join(Directory<T> directory) throws RpcException {
        return new FailfastClusterInvoker<T>(directory);
    }

}

2.6 FailsafeCluster

该FailsafeCluster 实现主要创建一个 带有 失败忽略功能的invoker,什么是失败忽略呢?这个失败忽略其实就是当调用发生失败,出现异常的时候只是打印error log,然后创建一个空的返回值返回,它与FailfastCluster 区别就是在这,快速失败 当调用异常的时候直接抛出异常,而FailsafeCluster 会将这个异常内部消化掉,返回一个空的结果,我们看下FailsafeCluster 源码:

public class FailsafeCluster implements Cluster {
    public final static String NAME = "failsafe";
    @Override
    public <T> Invoker<T> join(Directory<T> directory) throws RpcException {
        return new FailsafeClusterInvoker<T>(directory);
    }
}

2.7 ForkingCluster

该ForkingCluster 实现主要是创建 一个带有 并发请求功能的invoker对象返回,并发调用特定数量的服务提供者,通常用于要求实时操作,但需要浪费更多的服务资源。并发请求,获取那个最快响应回来的返回值。

public class ForkingCluster implements Cluster {
    public final static String NAME = "forking";
    @Override
    public <T> Invoker<T> join(Directory<T> directory) throws RpcException {
        return new ForkingClusterInvoker<T>(directory);
    }
}

2.8 MergeableCluster

该MergeableCluster 实现主要创建一个带有 合并返回值 功能的invoker

public class MergeableCluster implements Cluster {

    public static final String NAME = "mergeable";

    @Override
    public <T> Invoker<T> join(Directory<T> directory) throws RpcException {
        return new MergeableClusterInvoker<T>(directory);
    }

}

2.9 MockClusterWrapper

这个是Cluster 实现类的包装类,不管选择的 Cluster 实现类是什么,dubbo spi 都会为Cluster 实现类包装一层MockClusterWrapper,该包装类主要是创建 一个带有 mock功能的 包装invoker,这个invoker 会包Cluster 实现类 创建的invoker外面,起到包装的作用。

public class MockClusterWrapper implements Cluster {

    private Cluster cluster;

    public MockClusterWrapper(Cluster cluster) {
        this.cluster = cluster;
    }

    @Override
    public <T> Invoker<T> join(Directory<T> directory) throws RpcException {
        return new MockClusterInvoker<T>(directory,
                this.cluster.join(directory));
    }

}

3.总结

本篇我们主要是讲解了Cluster的接口与其对应的实现类的源码与功能,接下来的文章,我们会详细讲解实现类功能的具体实现。

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页