既然咱们的目的是阅读 Canal 源码,那么,首先就得掌握如何在自己的电脑上搭建 Canal 的源码环境,甚至是知道怎么对它们进行调试。本文展示了很多实操步骤,建议你都跟着操作一遍,否则很难会有特别深刻的认识。
一、环境准备
在阅读 Canal 源码之前,我们要先做一些必要的准备工作。这涉及到一些工具软件的安装,比如 Java、Maven、IDE、Git 等等。
如果你是在 Linux 或 Mac 系统下搭建环境,你需要安装 Java、IDE 和 Git;如果你使用的是 Windows,那么你需要全部安装它们。
本系列文章将统一使用下面的版本进行源码讲解。
- Oracle Java 8:我使用的是 Oracle 的 JDK 及 Hotspot JVM。如果你青睐于其他厂商或开源的 Java 版本(比如 OpenJDK),你可以选择安装不同厂商的 JVM 版本。
- Maven 3.6.3:虽然 Maven 的版本没有太大要求,但至少也要是 3.x.x 系列。我使用的是 Apache 的 Maven 的 3.6.3 版本。
- IDEA:本系列文章使用 IDEA 作为 IDE 来阅读和配置源码。我对 Eclipse 充满敬意,只是我个人比较习惯使用 IDEA。
- Git:安装 Git 主要是为了管理 Canal 源码版本,如果你要成为一名社区代码贡献值,Git 管理工具必不可少的。
二、构建 Canal 工程
等你准备好以上这些之后,我们就可以来构建 Canal 工程了。
首先,我们下载 Canal 源代码,方法很简答, 找一个干净的源码路径,然后执行下列命令去下载社区的 master 分支代码即可:
git clone https://github.com/alibaba/canal.git
在漫长的等待之后,你的路径上会新增一个名为canal的子目录,它就是 Canal 项目的根目录。如果在你的环境中,上面这条命令无法执行的话,你可以在浏览器中输入或直接在此处点击 https://codeload.github.com/alibaba/canal/zip/master 下载源码 ZIP 包并解压,只是这样你就失去了 Git 管理,你要手动连接到远程仓库,具体方法可以参考 Git文档。
下载完成后,你要进入工程所在的路径下,也就是进入到名为canal路径下,然后执行相应的命令来构建 Canal 工程。
你可以直接在终端运行下列命令编译即可:
mvn compile
下面,我用一张图给你展示下 Canal 工程的各个目录以及文件:
这里我简单介绍一些主要的组件。
- common 目录:定义了 Canal 的生命周期接口以及封装了各种工具类(基于 log 的 alarm 实现以及 zookeeper 客户端)。
- client 目录:存放与 canal 进行交互的客户端两种实现,提供给外部使用。
- example 目录:存放了一些 client 模块的使用案例,算是新手入门的必读资料吧。
- driver 目录:存放着与 MySQL 建立连接,并获取 binlog 二进制流的相关源码。
- dnsync 目录:存放着将二进制流解析成对应的 binlog 事件的源码。
- parse 目录:存放对各类 DML 和 DDL 事件解析的相关源码。
- filter 目录:存放着一套数据过滤器实现源码,比如可用于过滤只取某些表的数据。
- sink 目录:存放着对数据进行过滤、加工、分发的工作的源码。
- store 目录:存放着 借鉴了 Disrupter 的 RingBuffer 实现基于内存的数据存储管理方式,可通过配置定义内存的容量(memory size/item size),数据的放入依赖于可用位置,否则一直会等待空位出现。
- meta 目录:实现多种客户端订阅与消费信息的管理(memory/file/zookeeper),与 parse 模块中实现的解析位点管理器协同使用。
- instance 目录:其实是把 parse、sink、store 和 mate 模块组装在一起,为客户端提供服务。一个 server 可以有多个 instance,每个 instance 都会模拟成一个 MySQL 的 slave。
- protocol 目录:基于 google 开源的 protocol 实现的 canal 数据序列化的定义,也是与外部进行交互的实体协议定义。
- server 目录:Canal 服务器端。一个 server 代表一个 Canal 运行实例,对应一个 JVM。
- deployer 目录:部署模块。发布与配置目录,程序启动入口。通过该模块提供的 CanalLauncher 来启动 Canal Server。
如果那你要编译整个 Canal 工程并打包出一个可运行的二进制环境, 就需要运行下面的命令:
mvn clean package -Prelease # 指定环境为release
成功运行后,会在canal/target目录下生成四个二进制发布包,它们分别是:
- canal.adapter-1.1.4.tar.gz。它是 Canal 的全服务发布包,能够将数据发往其他异构库。
- canal.deployer-1.1.4.tar.gz。它仅是纯 Canal 服务的发布包,不含将数据发往异构环境的相关功能。
- canal.admin-1.1.4.tar.gz。它是管理 canal 服务 web 应用的发布包。
- canal.example-1.1.4.tar.gz。它是 canal 的客户端使用示例的发布包,你可以通过它学习如何使用如何从 canal 中拉取数据。
三、搭建源码阅读环境
上述内容介绍了如何使用 Maven 工具来构建 Canal 项目工程,下面再来带你看一下如何利用 IDEA 搭建 Canal 源码阅读环境。实际上,整个过程非常简单。我们打开 IDEA,点击“文件”,随后点击“打开”,选择上一章节中的 canal 文件路径即可。
我们此系列文章主要以 1.1.4 版本为主。所以需要切换到canal-1.1.4分支上。项目工程被导入之后,在 IDEA 的“Terminal”窗口执行下述命令切换分支。
git checkout canal-1.1.4
项目工程被导入之后,IDEA 会对项目进行自动构建,等构建完成之后,你可以找到 deployer 目录源码下的 CanalLauncher.java 文件。打开它,然后左键点击如下图示中的任意一个绿色三角形,选择“Debug ‘CanalLauncher.main()’”调试启动 Canal 服务。
完成上述步骤后,你不能在控制台看见任何输出,因为工程的日志信息通过 logback.xml 配置在了与 canal 同级目录的logs目录下。在 logs/canal/canal.log 中显示如下信息,则表示 canal 服务启动起来了。
2020-06-05 10:51:23.345 [main] INFO com.alibaba.otter.canal.deployer.CanalLauncher - ## set default uncaught exception handler
2020-06-05 10:51:23.381 [main] INFO com.alibaba.otter.canal.deployer.CanalLauncher - ## load canal configurations
2020-06-05 10:51:23.391 [main] INFO com.alibaba.otter.canal.deployer.CanalStarter - ## start the canal server.
2020-06-05 10:51:23.434 [main] INFO com.alibaba.otter.canal.deployer.CanalController - ## start the canal server[150.223.xxx.xxx(150.223.xxx.xxx):11111]
2020-06-05 10:51:24.785 [main] INFO com.alibaba.otter.canal.deployer.CanalStarter - ## the canal server is running now ......
Canal 的服务启动了,并不代表默认的 instance 也能正常工作了。instance 的运行状况可以在 logs/example/example.log 文件中获悉,根据日志的报错情况,在 deployer 模块下的资源配置文件夹下的 example/instance.properties 文件中调整目标数据库的连接信息,下述列举了该配置文件中与连接信息有关的属性及其默认值。
canal.instance.master.address=127.0.0.1:3306
canal.instance.dbUsername=canal
canal.instance.dbPassword=canal
正确运行 instance 的日志示例如下:
2020-06-05 10:51:23.917 [main] INFO c.a.o.c.i.spring.support.PropertyPlaceholderConfigurer - Loading properties file from class path resource [canal.properties]
2020-06-05 10:51:23.921 [main] INFO c.a.o.c.i.spring.support.PropertyPlaceholderConfigurer - Loading properties file from class path resource [example/instance.properties]
2020-06-05 10:51:24.201 [main] INFO c.a.o.c.i.spring.support.PropertyPlaceholderConfigurer - Loading properties file from class path resource [example/instance.properties]
2020-06-05 10:51:24.724 [main] INFO c.a.otter.canal.instance.spring.CanalInstanceWithSpring - start CannalInstance for 1-example
2020-06-05 10:51:24.738 [main] INFO c.a.otter.canal.instance.core.AbstractCanalInstance - start successful....
另外,虽然我的介绍不会涵盖测试用例的代码分析,但在我看来,弄懂测试用例是帮助你快速了解 Canal 组件的最有效的捷径之一。如果时间允许的话,我建议你多读一读 Canal 各个组件下的测试用例,它们通常都位于代码包的 src/test 目录下。