如何进行instance模块的源码解析

发布时间:2021-12-09 16:22:00 作者:柒染
来源:亿速云 阅读:140

如何进行instance模块的源码解析,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

1.基本结构

如何进行instance模块的源码解析

instance模块下面也分为三个子模块,core、manager、spring。

其中,core是instance的核心逻辑 。

而manager和spring只是两种不同的instance配置读取方式,manager通过http请求读取admin的配置,spring通过配置文件的方式读取。

主要控制逻辑我们在deployer模块源码分析中提到过,就是在CanalController类 的instanceGenerator,配置参数是canal.instance.global.mode

源码如下

如何进行instance模块的源码解析

2.core子模块

如何进行instance模块的源码解析

代码不多,就两个接口,两个类。

2.1 CanalInstanceGenerator接口

这个接口只有一个方法

如何进行instance模块的源码解析

具体实现就是开头提到的两种,PlainCanalInstanceGenerator和SpringCanalInstanceGenerator,分别在manager子模块和spring子模块中实现。

具体选择就是开头的那个canalController里面根据canal.instance.global.mode来选择。

2.2 CanalInstance接口

先看一张官方文档的图,这个前面的文章已经分析过了。

如何进行instance模块的源码解析

server代表一个canal-server运行实例,对应于一个jvm。server内部可以有多个instance。

Instance内部有4个主要组件:

在这个接口中,就定义了获取4个组件的方法,以及新版本增加的mqProducer的配置信息(mqProducer在server模块解析中介绍过了,可以回头去看看)

如何进行instance模块的源码解析

我们简单看下4个组件接口的各个实现类。

CanalEventParser接口实现类(paser模块):

CanalEventSink接口实现类(sink模块):

CanalEventStore接口实现类(store模块):

CanalMetaManager(meta模块):

关于这些实现的具体细节,我们在相应模块的源码分析时,进行讲解。目前只需要知道,一些组件有多种实现,因此组合工作方式有多种。

2.3 AbstractCanalInstance类

AbstractCanalInstance是canalInstance的抽象类,维护了相关组件的引用。

同时,也实现了canalInstance接口的subscribeChange方法。

如何进行instance模块的源码解析

这个抽象类有两个实现,CanalInstanceWithManager 和 CanalInstanceWithSpring。

如何进行instance模块的源码解析

AbstractCanalInstance的初始化过程都是在实现类中完成的。

如果选择admin控制模式,那就是在CanalInstanceWithManager中完成;如果是spring模式,就在CanalInstanceWithSpring中完成。 

这里有个小发现:

仔细看下实际代码调用我们发现,CanalInstanceWithManager是给ManagerCanalInstanceGenerator使用的,而这个generator实际上没有被使用到。如果使用admin模式,本文开头我们就看到了,使用了PlainCanalInstanceGenerator。PlainCanalInstanceGenerator里面的generate方法实现,其实跟SpringCanalInstanceGenerator差不多。就是从远端admin拉到配置,然后替换系统变量,然后再从spring的beanfactory中构建具体的实例。

2.3.1 subscribeChange() 方法

AbstractCanalInstance类实现了CanalInstance接口的subscribeChange方法。

我们看到,如果订阅关系发生变化,就做一些操作,这里看的话,主要就是更新了一下filter。

filter规定了需要订阅哪些库,哪些表。

如何进行instance模块的源码解析

2.3.2 start() 方法

启动没什么特别的逻辑,就是按照顺序依次启动各个组件。

顺序为 metaManager -> alarmHandler -> eventStore -> eventSink -> eventParser。

启动顺序主要跟依赖关系有关,元信息相关的管理跟所有都有关,所以metaManager最先启动,其他的按照彼此之间的关系一一启动。

如何进行instance模块的源码解析

这里我们发现,在启动eventParser的时候做了特殊处理,分别是beforeStartEventParser 和 afterStartEventParser。我们在2.3.4专门讲一下。

2.3.3 stop()方法

stop也没什么特殊的,就是依次关闭各个组件。

关闭的顺序就是start的逆过程。

这里就不贴代码了。

2.3.4 eventParserr的特殊处理

在start和stop方法中的eventParser前后都有特殊的处理,start的beforeStartEventParser 和 afterStartEventParser,Stop的beforeStopEventParser 和 afterStopEventParser。

这个其实跟eventParser的设计有关。

EventParser 设计

如何进行instance模块的源码解析

所以这两个beforexxx、afterxxxx方法做的主要是CanalLogPositionManager和CanalHAController的启停工作。

2.3.5 AbstractCanalInstance类 总结

可以看到AbstractCanalInstance除了负责启动和停止其内部组件,就没有其他工作了。

eventParser在AbstractCanalInstance中启动后,就会自行开启多线程任务dump数据,通过eventSink投递给eventStore。

而对eventStore的操作逻辑,实际上都是在CanalServerWithEmbedded中完成的,我们可以回顾一下CanalServerWithEmbedded中 getWithoutAck( ) 的相关逻辑。

包括:

所以,其实这里只是简单的启动和停止,组件的交互逻辑是在CanalServerWithEmbedded中get出instance的各个组件来进行实现的。

3.spring模块

前面提到了,PlainCanalInstanceGenerator里面的generate方法实现,其实跟SpringCanalInstanceGenerator差不多。就是从远端admin拉到配置,然后替换系统变量,然后再从spring的beanfactory中构建具体的实例。

所以我们重点关注spring子模块的配置方式即可。

就下面四个类

如何进行instance模块的源码解析

3.1 CanalInstanceWithSpring类

基于spring容器启动canal实例,方便独立于manager启动。

继承了AbstractCanalInstance,其实就是一系列组件的setter方法,就不贴源码了。

具体配置是基于spring的xml来做的.

当我们配置加载方式为spring时,创建的CanalInstance实例类型都是CanalInstanceWithSpring。canal将会寻找本地的spring配置文件来创建instance实例。canal默认提供了以下几种spring配置文件:

四个配置文件中,对CanalInstanceWithSpring都采用了同样的配置方式:

如何进行instance模块的源码解析

当然,具体每个组件的ref在不同配置文件中有所不同。

最主要的就是metaManager 和eventParser 这两个配置有所不同,可能在内存、文件或zk进行存储。

eventStore 、和eventSink 定义都是相同的,eventStore目前的开源版本中eventStore只有一种基于内存的实现,eventSink其作用是eventParser和eventStore的连接器,进行数据过滤,加工,分发的工作。不涉及存储,也就没有必要针对内存、file、或者zk进行区分。

3.2 SpringCanalInstanceGenerator类

这个是具体创建instance的逻辑。

如何进行instance模块的源码解析

顺便看下PlainCanalInstanceGenerator里面的实现,就是多了从远端拉取配置,然后用PropertyPlaceholderConfigurer进行了变量替换,然后还是用beanFactory来获取实例。

com.alibaba.otter.canal.instance.spring.support.PropertyPlaceholderConfigurer继承了org.springframework.beans.factory.config.PropertyPlaceholderConfigurer,设置动态properties,替换掉本地properties。

如何进行instance模块的源码解析

其实这个模块的东西比较少,没有什么特别复杂的逻辑。

我们来回顾下几个问题

主要有基于spring和基于远端配置两种方式,前者的实现在,后者的实现在PlainCanalInstanceGenerator

PlainCanalInstanceGenerator中使用了spring的PropertyPlaceholderConfigurer来覆盖配置

包括了parser、sink、store、metamanager等组件,但是只负责了启动和停止逻辑,具体交互逻辑还是在CanalServerWithEmbedded中实现的。

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注亿速云行业资讯频道,感谢您对亿速云的支持。

推荐阅读:
  1. 如何进行gunicorn Arbiter 源码解析
  2. 如何进行Redux的源码解析

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

instance

上一篇:hadoop中fs常用命令有哪些

下一篇:如何使用Python Impyla客户端连接Hive和Impala

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》