2 dubbo源码之集群容错实现
来源:互联网 发布:java判断是否有双引号 编辑:程序博客网 时间:2024/05/19 08:03
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
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
阅读全文
0 0
- 2 dubbo源码之集群容错实现
- Dubbo点滴(2)之集群容错
- dubbo源码解析-集群容错架构设计
- dubbo源码解析-集群容错架构设计
- Dubbo集群容错
- Dubbo集群容错
- dubbo集群容错模式
- 初识Dubbo 系列之8-Dubbo 集群容错
- 14. Dubbo原理解析-集群&容错之Cluster
- 15. Dubbo原理解析-集群&容错之目录服务Directory
- 16. Dubbo原理解析-集群&容错之router路由服务
- 17. Dubbo原理解析-集群&容错之负载均衡
- Dubbo之旅--集群容错和负载均衡
- Dubbo之旅--集群容错和负载均衡
- Dubbo之旅--集群容错和负载均衡
- dubbo——集群容错
- Dubbo学习(四):集群容错
- Dubbo服务集群容错配置
- 279. Perfect Squares(DP or BFS)
- MyEclipse maven build后控制台无输出
- Android 带点击事件的RecyclerView所用Adapter
- PythonStock(16):使用bokeh 展示,股票中的16个常用指标
- linux yum 安装mysql
- 2 dubbo源码之集群容错实现
- 菜单优化
- php中file_get_contents与curl性能比较分析
- Lua: Error during loading: [string "/usr/share/wireshark/init.lua"]:45: dofile has been disabled
- Android6.0动态权限
- CodeChef DEC17 D.Hamming Distance of arrays 构造,模拟.
- 内存管理
- BTree
- Servlet,过滤器,监听器,拦截器的区别