Dubbo源码分析----容错

本文深入分析了Dubbo的容错机制,包括AvailableCluster、BroadcastCluster、FailbackCluster、FailfastCluster、FailoverCluster、FailsafeCluster和ForkingCluster。FailbackCluster实现失败后重试,FailfastCluster快速失败不重试,FailoverCluster失败转移并有重试机制,ForkingCluster并行调用一个成功即返回。每个策略都有其特定的应用场景和实现细节。

先看下Dubbo官方的一张图
image.png

Cluster是容错的核心,官方的说法是

Cluster 将 Directory 中的多个 Invoker 伪装成一个 Invoker,对上层透明,伪装过程包含了容错逻辑,调用失败后,重试另一个

即Cluster是对外暴露的一个接口,内部返回一个集群版的Invoker,通过不同的容错策略,对从Directory中获取的invoker有不同的调用方式

下面看下代码实现

AvailableCluster

public class AvailableCluster implements Cluster {
   
   

    public static final String NAME = "available";

    public <T> Invoker<T> join(Directory<T> directory) throws RpcException {

        return new AbstractClusterInvoker<T>(directory) {
            public Result doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException {
                for (Invoker<T> invoker : invokers) {
                    if (invoker.isAvailable()) {
                        return invoker.invoke(invocation);
                    }
                }
                throw new RpcException("No provider available in " + invokers);
            }
        };

    }

}

这个策略很简单,就是从List

BroadcastCluster

public class BroadcastClusterInvoker<T> extends AbstractClusterInvoker<T> {
   
   
    public Result doInvoke(final Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException {
        checkInvokers(invokers, invocation);
        RpcContext.getContext().setInvokers((List)invokers);
        RpcException exception = null;
        Result result = null;
        for (Invoker<T> invoker: invokers) {
            try {
                result = invoker.invoke(invocation);
            } catch (RpcException e) {
                exception = e;
            } catch (Throwable e) {
                exception = e;
            }
        }
        if (exception != null) {
            throw exception;
        }
        return result;
    }

}

看名字就知道大概的意思,广播调用。看代码也很简单,遍历List

FailbackCluster

public class FailbackClusterInvoker<T> extends AbstractClusterInvoker<T> {
   
   
    private final ConcurrentMap<Invocation, AbstractClusterInvoker<?>> failed = new ConcurrentHashMap<Invocation, AbstractClusterInvoker<?>>();

    public FailbackClusterInvoker(Directory<T> directory){
        super(directory);
    }

    private void addFailed(Invocation invocation, AbstractClusterInvoker<?> router) {
        if (retryFuture == null) {
            synchronized (this) {
                if (retryFuture == null) {
                    retryFuture = scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {

                        public void run() {
                            // 收集统计信息
                            try {
                                retryFailed();
                            } catch (Throwable t) { // 防御性容错
                                logger.error("Unexpected error occur at collect statistic", t);
                            }
                        }
                    }, RETRY_FAILED_PERIOD, RETRY_FAILED_PERIOD, TimeUnit.MILLISECONDS);
                }
            }
        }
        failed.put(invocation, router);
    }

    protected Result doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException {
     
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值