作者:肥朝 原文地址:http://www.jianshu.com/p/8e007012367e
友情提示:欢迎关注公众号【芋道源码】。😈关注后,拉你进【源码圈】微信群和【肥朝】搞基嗨皮。
友情提示:欢迎关注公众号【芋道源码】。😈关注后,拉你进【源码圈】微信群和【肥朝】搞基嗨皮。
友情提示:欢迎关注公众号【芋道源码】。😈关注后,拉你进【源码圈】微信群和【肥朝】搞基嗨皮。
前言
本来是想把整个dubbo源码解析一次性弄完,再做成一个系列来发布的,但是正巧最近有位好朋友要去杭州面试,就和我交流了一下.本着对dubbo源码略有心得的心态,在交流过程中也发表了个人的一些粗劣的拙见.但是非常不幸的是,交流过程中我这位朋友问到了几个问题,我却没能回答得上,让我感到十分惭愧.故而将原计划提前,并且定期整理,做到定期更新一篇dubbo源码解析.好让自己的知识盲点尽早暴露出来.本篇讲的就是dubbo的一个重要概念,
集群容错
.既然你已经在看源码解析了,那么我就假设你对dubbo的使用上有一定的经验,并且看过了dubbo的官网的对集群容错的简单介绍
之前有写过源码解析的一些拙见,例如别怕,手把手带你撕、拉、扯下SpringMVC的外衣, 别怕看源码,一张图搞定Mybatis的Mapper原理,但是经过一些思考还是有比较多的缺陷,这主要表现在太猴急,导致前戏不足,上来就直接进入源码,没有铺垫概念.大多数人看源码主要存在的问题是,层级结构深,导致进了两三个方法之后,根本不知道自己在哪,久而久之,对看源码产生了恐惧
所以本篇尝试改变之前的风格,总结起来就是先总体,后局部.也就是先把需要注意的概念先抛出来,把整体架构图先画出来.让读者拿着”地图”跟着我的脚步,并且每一步我都提醒,现在我们在哪,我们下一步要做什么,这样才不会迷失方向.
前期铺垫
这张是官网的对于集群容错的架构设计图,即使你有一定的使用经验,第一眼看到这个图可能还是有些懵逼.因为这个图是从设计的角度画出来的,而不是使用的角度.但是即使这个图你看不懂也不影响你对本文的阅读,但是你必须要记住三个关键词,因为这三个关键词接下来会贯穿全文,他们就是
Directory
,
Router
,
LoadBalance
再接下来给大家一张”地图”,”地图”上我已经标记了序号,再下面的源码分析中,我也会实时提醒我们所在的位置,以至于不会迷失方向.
环境准备
既然是集群,那么首先要启动两个
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
在
Router
中,将上一步的全部
invokers
挑选出能正常执行的
invokers
对应到”地图”,也就是序号5和序号7.(再次提醒,一定要紧跟地图的序号,不然很容易迷失方向)
从上面步骤我们也知道,已经挑选出能正常执行的
invokers
了,但是假如2个做集群,但是这两个都是正常的,我到底要执行哪一个呢?带着这个问题,我们继续往下看
根据官网的描述
在集群调用失败时,Dubbo 提供了多种容错方案,缺省为 failover 重试。
所以这个时候是到了
FailoverClusterInvoker
类,但是如果你配置的是
FailfastCluster(快速失败)
,
FailsafeCluster(失败安全)
,
FailbackCluster(失败自动恢复)
,
ForkingCluster(并行调用多个服务器,只要一个成功即返回)
,
BroadcastCluster(广播调用所有提供者,逐个调用,任意一台报错则报错)
他也会到达相应的类
下面就要开始第三个关键词浮出水面,也就是
LoadBalance(负载均衡)
,此时的位置是序号11,仔细留心源码的注释,其实这里可以出一个面试题,比如
dubbo的负载均衡策略是怎么样的?
为什么这可以作为一道面试题,因为他可以区分三个层次的人.
根据前面我们知道,现在已经有两个备选的
invokers
,但是究竟哪一个能执行,这个需要
LoadBalance
来决定.这里涉及到了一定的算法,后面我也会有一篇文章加以介绍.剧透一下,这个在
2.5.4
的版本中,这个算法还是存在一些小的bug,此时我们的位置是序号13
到达终点站.我们回忆总结一下,文初提到的三个关键词,在这个集群容错的整体架构过程中,dubbo究竟做了什么.其实也就是三件事
在
Directory
中找出本次集群中的全部
invokers
在
Router
中,将上一步的全部
invokers
挑选出能正常执行的
invokers
在
LoadBalance
中,将上一步的能正常的执行
invokers
中,根据配置的负载均衡策略,挑选出需要执行的
invoker
在
Router
中,将上一步的全部
invokers
挑选出能正常执行的
invokers
写在末尾
本文也到达尾声,后面还会不定期更新dubbo的源码解析(包括dubbo内核,服务发布和订阅,集群容错,编码和解码),鉴于本文是整体架构解析,后面还会对这文中提到的三个关键字做详细的解析.鉴于本人才疏学浅,不对的地方还望斧正,也欢迎关注我的简书,名称为
肥朝