您的位置:首页 > 其它

2 dubbo源码之集群容错实现

2017-12-08 17:49 387 查看
dubbo提供了多种集群容错方式:Failover(失败自动切换)、Failfast(快速失败)、Failsafe(失败安全)、Failback(失败自动恢复)、Forking(并行调用多个服务器)

dubbo官网原文介绍:http://dubbo.io/books/dubbo-user-book/demos/fault-tolerent-strategy.html

集群模式配置如下:

<dubbo:service cluster="failover" />



<dubbo:reference cluster="failover" />

客户端启动,引用远程服务接口时:

ReferenceConfig.java中有两个静态成员变量:

 

 private static final Protocol refprotocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();

 private static final Cluster cluster = ExtensionLoader.getExtensionLoader(Cluster.class).getAdaptiveExtension();

通过扩展点获取Protocol对象为动态生成的Protocol$Adaptive.java的对象,Cluster对象也是动态生成的Cluster$Adaptive的对象

Protocol$Adaptive.refer()方法中,通过getExtension(name)获取对象时,会通过dubbo的IOC将cluster的扩展点对象设置到Protocol实现类的cluster属性,值为:Cluster$Adaptive对象

在RegisterProtocol.doRefer()方法中cluster.join(directory),即Cluster$Adaptive.join()

动态生成的Cluster$Adaptive的源码为:

public class Cluster$Adaptive implements com.alibaba.dubbo.rpc.cluster.Cluster {

    public com.alibaba.dubbo.rpc.Invoker join(com.alibaba.dubbo.rpc.cluster.Directory arg0) throws com.alibaba.dubbo.rpc.RpcException {

        if (arg0 == null)

            throw new IllegalArgumentException("com.alibaba.dubbo.rpc.cluster.Directory argument == null");

        if (arg0.getUrl() == null)

            throw new IllegalArgumentException("com.alibaba.dubbo.rpc.cluster.Directory argument getUrl() == null");

        com.alibaba.dubbo.common.URL url = arg0.getUrl();

        String extName = url.getParameter("cluster", "failover");

        if (extName == null)

            throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.cluster.Cluster) name from url(" + url.toString() + ") use keys([cluster])");

        com.alibaba.dubbo.rpc.cluster.Cluster extension = (com.alibaba.dubbo.rpc.cluster.Cluster) ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.cluster.Cluster.class).getExtension(extName);

        return extension.join(arg0);

    }

}

其中extName是在url的参数中获取的,默认为failover,

默认的failover,扩展点对象extension为FailoverCluster对象,在FailoverCluster.join()方法中new FailoverClusterInvoker

在此处可以看到,集群模式配置再次起到了作用。

集群模式是如何工作的呢?

客户端调用远程服务接口方法时,例如:

private DemoService demoService;

public void test(){

String result = demoService.sayHello();

}

该处的demoService.sayHello()即为客户端调用远程服务方法

远程服务接口对象是有JDK动态代理生成的(不清楚的请看上一篇文章),而dubbo是由InvokerInvocationHandler实现的InvocationHandler接口

在远程调用过程中,其实就是调用InvokerInvocationHandler.invoker方法。

源码如下:

public class InvokerInvocationHandler implements InvocationHandler {

    private final Invoker<?> invoker;

    public InvokerInvocationHandler(Invoker<?> handler) {

        this.invoker = handler;

    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        String methodName = method.getName();

        Class<?>[] parameterTypes = method.getParameterTypes();

        if (method.getDeclaringClass() == Object.class) {

            return method.invoke(invoker, args);

        }

        if ("toString".equals(methodName) && parameterTypes.length == 0) {

            return invoker.toString();

        }

        if ("hashCode".equals(methodName) && parameterTypes.length == 0) {

            return invoker.hashCode();

        }

        if ("equals".equals(methodName) && parameterTypes.length == 1) {

            return invoker.equals(args[0]);

        }

        return invoker.invoke(new RpcInvocation(method, args)).recreate();

    }

}

而此处使用到的invoker就是上面Cluster的动态Adaptive类join方法返回的invoker,默认是FailoverCluster.join()方法new的FailoverClusterInvoker对象

下面来看各种集群模式是如何工作的:

1、FailoverCluster
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: