技术标签: Dubbo
Dubbo源码解析系列文章均来自肥朝简书
本来是想把整个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
本文也到达尾声,后面还会不定期更新dubbo的源码解析(包括dubbo内核,服务发布和订阅,集群容错,编码和解码),鉴于本文是整体架构解析,后面还会对这文中提到的三个关键字做详细的解析.鉴于本人才疏学浅,不对的地方还望斧正.
初始化SDA数据线和SCL时钟线void IIC_Init(void){ GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );//使能GPIOB GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;//PB6,PB7 GPIO_InitStructure.GPIO_Mode = GP_iic实验心得体会
注意:只能使用gif的图片from tkinter import *tk = Tk()tk.title('cowboy')photo = PhotoImage(file="E:/image/B.gif")theLabel = Label(tk, image=photo)label = Label(tk, text="hello", font=('heiti', 20), fg='r..._tkinter 教程显示图片
首先明白一下字符串和字符数组的区别第一,字符数组和字符串是不同的,字符数组可以不含有'\0',而字符串的最后一个字符必然是'\0'。第二,比较两字符串,是从两字符串的第一位开始比较ASCII码,第一位相同则看第二位,以止类推,例如“AB"是大于“CDEFGHIJK"的。第三,字符串中只要出现'\0‘,后面的根本就不存在了,字符数组是,如:char s[5]={'a','b','\0’,'e',
rootkit本来一直都是*nix系统中流行的一种后门,但现在win下也开始流行rootkit了,由于rootkit一般具有隐藏自己的特性,所以并不是象一般后门那样可以轻易的找出来.现在win下最流行的后门是国外的那个hxdef,代码也已经发放了.hxdef一个不足是主程序在隐藏自己的进程上做得不好,已经有多种方法可以将它本身的隐藏进程查出来,但将来的rootkit会在隐藏进程方面做得更好,或者会
一:什么是点云数据 点云数据是指在一个三维坐标系统中的一组向量的集合。这些向量通常以X,Y,Z三维坐标的形式表示,而且一般主要用来代表一个物体的外表面形状。不经如此,除(X,Y,Z)代表的几何位置信息之外,点云数据还可以表示一个点的RGB颜色,灰度值,深度,分割结果等。Eg..Pi={Xi, Yi, Zi,…….}表示空间中的一个点,则Point Cloud={P1, P2,..._isite studio
如图,模型基本结构是BERT,是model,而BERTLM集成了Bert,NSP,MLM,是模型结构的核心。在数据的处理中,核心是BERTDataset训练或者评估的时候,调用了BERTTrainer,他使用了BertDataset的数据来进行训练与迭代..._codertimo/bert-pytorch
react-native run-android执行虚拟机红屏提示:unable to load script from assets'index.android.bundle'.Make sure your bundle is packaged correctly or your're running apackager server.看提示是无法加载资源文件中的script文件
************* 异常文本 *************System.Security.SecurityException: 不允许所请求的注册表访问权。这是没有取得管理员权限的问题,我们要设置为每次运行默认获取系统管理员权限.1、在Visual Studio 中--解决方案资源管理器--右键项目名称--属性,找到“安全性”选项,勾选“启用ClickOnce安全设置”:2、这时,在项目下面会多出一个“app.manifest”的文件,选中它,并找到代码段&l.._c#不允许所请求的注册表访问权
使用eclipse真的有年头了,相信java程序员没有不知道它的,最近在给团队中新来的应届生做指导,专门讲解了一下Eclipse开发环境的搭建过程,一是帮助他们尽快的熟悉IDE的使用,二也是保证团队开发环境的一致性(顺便说一下,这点在敏捷开发团队中尤为重要,方便知识传播,提升团队快速响应能力)。培训的过程中想起了自己当年初涉java时的情景,不免感慨万千啊。正所谓“工欲善其事必先利其器”,话不多说..._基于开源框架的软件项目设计与实现,进一步熟悉eclipse java ee ide 开发环境
class Person(object): def __init__(self,name): self.name = name def getname(self): print self.nameclass Student(Person): def __init__(self,name,age): #P...
from openpyxl import Workbookfrom openpyxl.utils import get_column_letter # get_colum_letter(2) 返回第二列的编号:Bimport datetimewb = Workbook()file_name = 'workbook_1.xlsx'ws1 = wb.activews1.title = 'range names' # 写入40行 599列for row in range(1,42..._openpyxl确定单元格数据类型
1 np.arange(),类似于range,通过指定开始值,终值和步长来创建表示等差数列的一维数组,注意该函数和range一样结果不包含终值。>>> np.arange(10)array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])>>> np.arange(0,1,0.1)array([ 0. , 0.1, 0.2, 0.3, 0.4, 0..._np.arange和np.arange创建数组有什么区别