本来是想把整个dubbo源码解析一次性弄完,再做成一个系列来发布的,但是正巧最近有位好朋友要去杭州面试,就和我交流了一下.本着对dubbo源码略有心得的心态,在交流过程中也发表了个人的一些粗劣的拙见.但是非常不幸的是,交流过程中我这位朋友问到了几个问题,我却没能回答得上,让我感到十分惭愧.故而将原计划提前,并且定期整理,做到定期更新一篇dubbo源码解析.好让自己的知识盲点尽早暴露出来.本篇讲的就是dubbo的一个重要概念,集群容错
.既然你已经在看源码解析了,那么我就假设你对dubbo的使用上有一定的经验,并且看过了dubbo的官网的对集群容错的简单介绍
之前有写过源码解析的一些拙见,例如别怕,手把手带你撕、拉、扯下SpringMVC的外衣, 别怕看源码,一张图搞定Mybatis的Mapper原理,但是经过一些思考还是有比较多的缺陷,这主要表现在太猴急,导致前戏不足,上来就直接进入源码,没有铺垫概念.大多数人看源码主要存在的问题是,层级结构深,导致进了两三个方法之后,根本不知道自己在哪,久而久之,对看源码产生了恐惧
所以本篇尝试改变之前的风格,总结起来就是先总体,后局部.也就是先把需要注意的概念先抛出来,把整体架构图先画出来.让读者拿着"地图"跟着我的脚步,并且每一步我都提醒,现在我们在哪,我们下一步要做什么,这样才不会迷失方向.
官网介绍图.png
这张是官网的对于集群容错的架构设计图,即使你有一定的使用经验,第一眼看到这个图可能还是有些懵逼.因为这个图是从设计的角度画出来的,而不是使用的角度.但是即使这个图你看不懂也不影响你对本文的阅读,但是你必须要记住三个关键词,因为这三个关键词接下来会贯穿全文,他们就是Directory
,Router
,LoadBalance
再接下来给大家一张"地图","地图"上我已经标记了序号,再下面的源码分析中,我也会实时提醒我们所在的位置,以至于不会迷失方向.
执行时序图.png
既然是集群,那么首先要启动两个Provider
,我这里是一个虚拟机,一个本地的方式,因为环境准备不是本文重点,因此略过.本文所用到的源码是2.5.4
版本,可以在guihub
上找到.
这次示例选用的源码用dubbo-demo
的dubbo-demo-consumer
,如果对dubbo原理有些简单的了解就知道,他给接口注入的不是接口的实现类,而是一个代理类,如下图
接着自然是到了代理类的invoke方法里,从图中我们也可以看出,他用的是jdk的动态代理
下面要开始紧盯着地图了,他现在就要开始执行地图中的序号1,此时我们抵达MockClusterInvoker
这个类
执行invoke
就要开始进入到集群,也就是Cluster
,现在第一个关键词Directory
已经浮出水面了
现在到了AbstractDirectory
,也就是序号3
这个methodInvokerMap
也比较重要,后面的文章会讲一下这个,但是我们这部分代码就可以从出,他是要从methodInvokerMap
中取出invokers
如图所示
将invokers返回后(序号5),下面来到了第二个关键词,Router
,开始进入路由,现在我们到了序号6,此时到了MockInvokersSelector
类,不要看类名和Router
没有关系,其实他是Router
接口的实现类,从官网的介绍图中我们也可以看到Router
分为Script
和Condition
两种,翻译过来也就是脚本路由
和条件路由
这个后面再详细介绍,本篇主要介绍整体架构
源码的命名是很规范的,从getNormalInvokers
就可以得知,他是要拿到能正常执行的invokers
,并将其返回.也就是序号7
这个时候我们再次回到了AbstractClusterInvoker
这个类,我们先不急着往下走,先适时做个总结.因为三个关键词,现在都已经出现了两个,那这个时候要回忆一下上面这些步骤,做一个总结.上面出现的这两个关键词,其实无非就是做两件事
Directory
中找出本次集群中的全部invokers
Router
中,将上一步的全部invokers
挑选出能正常执行的invokers
对应到"地图",也就是序号5和序号7.(再次提醒,一定要紧跟地图的序号,不然很容易迷失方向)
从上面步骤我们也知道,已经挑选出能正常执行的invokers
了,但是假如2个做集群,但是这两个都是正常的,我到底要执行哪一个呢?带着这个问题,我们继续往下看
根据官网的描述
在集群调用失败时,Dubbo 提供了多种容错方案,缺省为 failover 重试。
所以这个时候是到了FailoverClusterInvoker
类,但是如果你配置的是Failfast Cluster(快速失败)
,Failsafe Cluster(失败安全)
,Failback Cluster(失败自动恢复)
,Forking Cluster(并行调用多个服务器,只要一个成功即返回)
,Broadcast Cluster(广播调用所有提供者,逐个调用,任意一台报错则报错)
他也会到达相应的类
下面就要开始第三个关键词浮出水面,也就是LoadBalance(负载均衡)
,此时的位置是序号11
根据前面我们知道,现在已经有两个备选的invokers
,但是究竟哪一个能执行,这个需要LoadBalance
来决定.这里涉及到了一定的算法,后面我也会有一篇文章加以介绍.剧透一下,这个在2.5.4
的版本中,这个算法还是存在一些小的bug,此时我们的位置是序号13
到达终点站.我们回忆总结一下,文初提到的三个关键词,在这个集群容错的整体架构过程中,dubbo究竟做了什么.其实也就是三件事
Directory
中找出本次集群中的全部invokers
Router
中,将上一步的全部invokers
挑选出能正常执行的invokers
LoadBalance
中,将上一步的能正常的执行invokers
中,根据配置的负载均衡策略,挑选出需要执行的invoker
作者:肥朝 链接:https://www.jianshu.com/p/8e007012367e