Dubbo 源码解析 —— 集群容错架构设计

Dubbo 源码解析 —— 集群容错架构设计

作者:肥朝 原文地址:http://www.jianshu.com/p/8e007012367e

友情提示:欢迎关注公众号【芋道源码】。😈关注后,拉你进【源码圈】微信群和【肥朝】搞基嗨皮。

友情提示:欢迎关注公众号【芋道源码】。😈关注后,拉你进【源码圈】微信群和【肥朝】搞基嗨皮。

友情提示:欢迎关注公众号【芋道源码】。😈关注后,拉你进【源码圈】微信群和【肥朝】搞基嗨皮。

前言

本来是想把整个dubbo源码解析一次性弄完,再做成一个系列来发布的,但是正巧最近有位好朋友要去杭州面试,就和我交流了一下.本着对dubbo源码略有心得的心态,在交流过程中也发表了个人的一些粗劣的拙见.但是非常不幸的是,交流过程中我这位朋友问到了几个问题,我却没能回答得上,让我感到十分惭愧.故而将原计划提前,并且定期整理,做到定期更新一篇dubbo源码解析.好让自己的知识盲点尽早暴露出来.本篇讲的就是dubbo的一个重要概念, 集群容错.既然你已经在看源码解析了,那么我就假设你对dubbo的使用上有一定的经验,并且看过了dubbo的官网的对集群容错的简单介绍

之前有写过源码解析的一些拙见,例如别怕,手把手带你撕、拉、扯下SpringMVC的外衣, 别怕看源码,一张图搞定Mybatis的Mapper原理,但是经过一些思考还是有比较多的缺陷,这主要表现在太猴急,导致前戏不足,上来就直接进入源码,没有铺垫概念.大多数人看源码主要存在的问题是,层级结构深,导致进了两三个方法之后,根本不知道自己在哪,久而久之,对看源码产生了恐惧

所以本篇尝试改变之前的风格,总结起来就是先总体,后局部.也就是先把需要注意的概念先抛出来,把整体架构图先画出来.让读者拿着"地图"跟着我的脚步,并且每一步我都提醒,现在我们在哪,我们下一步要做什么,这样才不会迷失方向.

前期铺垫

Dubbo 源码解析 —— 集群容错架构设计

这张是官网的对于集群容错的架构设计图,即使你有一定的使用经验,第一眼看到这个图可能还是有些懵逼.因为这个图是从设计的角度画出来的,而不是使用的角度.但是即使这个图你看不懂也不影响你对本文的阅读,但是你必须要记住三个关键词,因为这三个关键词接下来会贯穿全文,他们就是 Directory, Router, LoadBalance

再接下来给大家一张"地图","地图"上我已经标记了序号,再下面的源码分析中,我也会实时提醒我们所在的位置,以至于不会迷失方向.

Dubbo 源码解析 —— 集群容错架构设计

环境准备

既然是集群,那么首先要启动两个 Provider,我这里是一个虚拟机,一个本地的方式,因为环境准备不是本文重点,因此略过.本文所用到的源码是 2.5.4版本,可以在 guihub上找到.

正式发车

这次示例选用的源码用 dubbo-demodubbo-demo-consumer,如果对dubbo原理有些简单的了解就知道,他给接口注入的不是接口的实现类,而是一个代理类,如下图

Dubbo 源码解析 —— 集群容错架构设计

接着自然是到了代理类的invoke方法里,从图中我们也可以看出,他用的是 jdk的动态代理

Dubbo 源码解析 —— 集群容错架构设计

下面要开始紧盯着地图了,他现在就要开始执行地图中的序号1,此时我们抵达 MockClusterInvoker这个类

Dubbo 源码解析 —— 集群容错架构设计

执行 invoke就要开始进入到集群,也就是 Cluster,现在第一个关键词 Directory已经浮出水面了

Dubbo 源码解析 —— 集群容错架构设计

Dubbo 源码解析 —— 集群容错架构设计

现在到了 AbstractDirectory,也就是序号3

Dubbo 源码解析 —— 集群容错架构设计

这个 methodInvokerMap也比较重要,后面的文章会讲一下这个,但是我们这部分代码就可以从出,他是要从 methodInvokerMap中取出 invokers如图所示

Dubbo 源码解析 —— 集群容错架构设计

Dubbo 源码解析 —— 集群容错架构设计

将invokers返回后(序号5),下面来到了第二个关键词, Router,开始进入路由,现在我们到了序号6,此时到了 MockInvokersSelector类,不要看类名和 Router没有关系,其实他是 Router接口的实现类,从官网的介绍图中我们也可以看到 Router分为 ScriptCondition两种,翻译过来也就是 脚本路由条件路由这个后面再详细介绍,本篇主要介绍整体架构

Dubbo 源码解析 —— 集群容错架构设计

源码的命名是很规范的,从 getNormalInvokers就可以得知,他是要拿到能正常执行的 invokers,并将其返回.也就是序号7

Dubbo 源码解析 —— 集群容错架构设计

Dubbo 源码解析 —— 集群容错架构设计

这个时候我们再次回到了 AbstractClusterInvoker这个类,我们先不急着往下走,先适时做个总结.因为三个关键词,现在都已经出现了两个,那这个时候要回忆一下上面这些步骤,做一个总结.上面出现的这两个关键词,其实无非就是做两件事

  • Directory中找出本次集群中的全部 invokers


  • Router中,将上一步的全部 invokers挑选出能正常执行的 invokers


对应到"地图",也就是序号5和序号7.(再次提醒,一定要紧跟地图的序号,不然很容易迷失方向)

从上面步骤我们也知道,已经挑选出能正常执行的 invokers了,但是假如2个做集群,但是这两个都是正常的,我到底要执行哪一个呢?带着这个问题,我们继续往下看

Dubbo 源码解析 —— 集群容错架构设计

Dubbo 源码解析 —— 集群容错架构设计

根据官网的描述

在集群调用失败时,Dubbo 提供了多种容错方案,缺省为 failover 重试。

所以这个时候是到了 FailoverClusterInvoker类,但是如果你配置的是 FailfastCluster(快速失败), FailsafeCluster(失败安全), FailbackCluster(失败自动恢复), ForkingCluster(并行调用多个服务器,只要一个成功即返回), BroadcastCluster(广播调用所有提供者,逐个调用,任意一台报错则报错)他也会到达相应的类

Dubbo 源码解析 —— 集群容错架构设计

Dubbo 源码解析 —— 集群容错架构设计

下面就要开始第三个关键词浮出水面,也就是 LoadBalance(负载均衡),此时的位置是序号11,仔细留心源码的注释,其实这里可以出一个面试题,比如

dubbo的负载均衡策略是怎么样的?

为什么这可以作为一道面试题,因为他可以区分三个层次的人.

  • 如果是没有使用过,或者一直停留在使用层次的人,肯定不会留级到这个负载均衡策略.

  • 根据官网介绍 在集群负载均衡时,Dubbo提供了多种均衡策略,缺省为random随机调用。如果能回答出,缺省为随机调用的,说明还是有一定的使用经验,留意到官网的介绍

  • 如果能回答出,缺省为随机调用,但是如果集群的数量为2,那么将退化成轮询.如果能回答到这个,那这个人就是有一定追求,不仅留心文档介绍,而且是看过源码,注意细节的人(比如本文作者肥朝 ^_^ )

Dubbo 源码解析 —— 集群容错架构设计

根据前面我们知道,现在已经有两个备选的 invokers,但是究竟哪一个能执行,这个需要 LoadBalance来决定.这里涉及到了一定的算法,后面我也会有一篇文章加以介绍.剧透一下,这个在 2.5.4的版本中,这个算法还是存在一些小的bug,此时我们的位置是序号13

Dubbo 源码解析 —— 集群容错架构设计

Dubbo 源码解析 —— 集群容错架构设计

到达终点站.我们回忆总结一下,文初提到的三个关键词,在这个集群容错的整体架构过程中,dubbo究竟做了什么.其实也就是三件事

  • Directory中找出本次集群中的全部 invokers


  • Router中,将上一步的全部 invokers挑选出能正常执行的 invokers


  • LoadBalance中,将上一步的能正常的执行 invokers中,根据配置的负载均衡策略,挑选出需要执行的 invoker


Dubbo 源码解析 —— 集群容错架构设计

写在末尾

本文也到达尾声,后面还会不定期更新dubbo的源码解析(包括dubbo内核,服务发布和订阅,集群容错,编码和解码),鉴于本文是整体架构解析,后面还会对这文中提到的三个关键字做详细的解析.鉴于本人才疏学浅,不对的地方还望斧正,也欢迎关注我的简书,名称为 肥朝


发表评论