【Canal】Canal学习笔记 朴灿烈づ我的快乐病毒、 2023-02-13 17:09 312阅读 0赞 **目录** 一、Canal 介绍 1.1 Canal 概述 1.2 Canal 原理 二、Canal 安装和使用 2.1 mysql 准备 2.1.1 开启 mysql 的 binlog 模式 2.1.2 创建同步账号 2.1.3 重启 mysql 容器 2.2 Canal 容器安装和使用 2.2.1 下载镜像和安装 2.2.2 Canal 配置 2.3 Canal 微服务搭建 2.3.1 安装 Canal 开源项目到本地 maven 仓库 2.3.3 创建 CanalDataEventListerner.java : 2.3.4 新建启动类 2.3.5 编写微服务配置文件 2.4 测试 -------------------- # 一、Canal 介绍 # ## 1.1 Canal 概述 ## Canal是阿里巴巴旗下的一款开源项目,纯Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。 简单来说就是用来监控数据库数据的变化,从而获得新增数据或修改数据的项目框架,目前主要支持了MySQL。 ## 1.2 Canal 原理 ## ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDE2MzMx_size_16_color_FFFFFF_t_70][] **原理:** * canal 模拟 mysql slave 的交互协议,伪装自己为 mysql slave, 向mysql master 发送 dump 协议 * mysql master 收到 dump 请求,开始推送 binary log 给 slave(即 canal) * canal 解析 binary log 对象(原始为byte流) 由于 canal是基于mysql的主从模式实现的,所以必须先开启 binlog # 二、Canal 安装和使用 # ## 2.1 mysql 准备 ## ### 2.1.1 开启 mysql 的 binlog 模式 ### 由于 mysql 是使用 docker 部署的,进入 docker 修改 mysql 的配置 # 进入 mysql 的 docker 容器内 docker exec -it mysql /bin/bash # 进入 mysql 对应的配置文件 cd /etc/mysql/mysql.conf.d # 修改配置文件 vim mysqld.cnf ![20200529231103984.png][] log-bin=/var/lib/mysql/mysql-bin # 指定日志文件存储的位置 server-id=12345 # 当前这个mysql数据库的唯一标识 ### 2.1.2 创建同步账号 ### 由于 Canal 要进入 mysql 读取数据,出于安全考虑,需要对 Canal 创建用户并赋予权限 # 创建账号 %表示能在任意机器登录 by 'xxx' 表示密码为canal create user canal@'%' IDENTIFIED by 'canal'; # 授权 依次为:查询权限、主从复制权限、主从复制客户端权限、超级权限 # *.* 表示 任意数据库.任意表 都拥有相关权限 # 结合表示: 任意机器上以canal账号登录的用户对mysql中任意数据库和任意表都拥有上述权限 GRANT SELECT, PEPLICATION SLAVE, REPLICATION CLIENT, SUPER ON *.* TO 'canal'@'%''; # 刷新数据库 FLUSH PRIVILEGES; ### **2.1.3 重启 mysql 容器** ### docker restart canal ## 2.2 Canal 容器安装和使用 ## ### 2.2.1 下载镜像和安装 ### # 下载镜像 docker pull docker.io/canal/canal-server # 安装 docker run -p 11111:11111 --name canal -d docker.io/canal/canal-server #-p 端口映射 ### 2.2.2 Canal 配置 ### 进入 Canal 容器 # 进入 canal 容器 docker exec -it canal /bin/bash # 进入配置文件夹 cd /home/admin/canal-server/conf ![20200529233144653.png][] 修改 Canal 的数据库唯一标识,改成唯一的 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDE2MzMx_size_16_color_FFFFFF_t_70 1][] 修改同步配置 vi ./example/instance.properties ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDE2MzMx_size_16_color_FFFFFF_t_70 2][] ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDE2MzMx_size_16_color_FFFFFF_t_70 3][] ![20200529234029437.png][] ![2020052923421255.png][] ## 2.3 Canal 微服务搭建 ## ### **2.3.1 安装 Canal 开源项目到本地 maven 仓库** ### 在搭建 Canal 时使用了一个开源项目,实现了 Springboot 和 Canal 的集成。 [https://github.com/chenqian56131/spring-boot-starter-canal][https_github.com_chenqian56131_spring-boot-starter-canal] 搭建: 找到项目目录,使用命令安装到本地 maven 仓库 mvn install ![20200530001305881.png][] ![20200530001348395.png][] **2.3.2 创建微服务项目** 创建 maven 项目,并加入依赖 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <!-- canal依赖 --> <dependency> <groupId>com.xpand</groupId> <artifactId>starter-canal</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies> ### 2.3.3 创建 CanalDataEventListerner.java : ### ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDE2MzMx_size_16_color_FFFFFF_t_70 4][] package com.changgou.canal; import com.alibaba.otter.canal.protocol.CanalEntry; import com.changgou.content.feign.ContentFeign; import com.xpand.starter.canal.annotation.*; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; /** * 实现mysql数据监听 */ @CanalEventListener @Slf4j public class CanalDataEventListener222 { @Autowired private ContentFeign contentFeign; @Autowired private StringRedisTemplate stringRedisTemplate; /** * @InsertListenPoint 增加监听 * @param eventType 当前操作的类型: 增加数据 * @param rowData 发生变更的一行数据 */ @InsertListenPoint public void onEventInsert(CanalEntry.EventType eventType, CanalEntry.RowData rowData) { for (CanalEntry.Column column : rowData.getAfterColumnsList()) { log.info("增加: 列名:" + column.getName() + "------ 变更的数据:" + column.getValue()); } } /** * @UpdateListenPoint 修改监听 * @param eventType 当前操作的类型: 增加数据 * @param rowData 发生变更的一行数据 */ @UpdateListenPoint public void onEventUpdate(CanalEntry.EventType eventType, CanalEntry.RowData rowData) { log.info("==================================================================================="); for (CanalEntry.Column column : rowData.getBeforeColumnsList()) { log.info("修改前: 列名:" + column.getName() + "------ 变更的数据:" + column.getValue()); } log.info("==================================================================================="); for (CanalEntry.Column column : rowData.getAfterColumnsList()) { log.info("修改后: 列名:" + column.getName() + "------ 变更的数据:" + column.getValue()); } } /** * @DeleteListenPoint 删除监听 * @param eventType 当前操作的类型: 增加数据 * @param rowData 发生变更的一行数据 */ @DeleteListenPoint public void onEventDel(CanalEntry.EventType eventType, CanalEntry.RowData rowData) { for (CanalEntry.Column column : rowData.getBeforeColumnsList()) { log.info("删除前:列名:" + column.getName() + "------ 变更的数据:" + column.getValue()); } } /** * @ListenPoint 自定义监听 * @param eventType 当前操作的类型: 增加数据 * @param rowData 发生变更的一行数据 */ @ListenPoint( destination = "example", // 指定Canal实例的地址 schema = {"changgou_content"}, // 指定监听的数据库 table = {"tb_content", "tb_content_category"}, // 指定监控的表 eventType = { CanalEntry.EventType.DELETE, CanalEntry.EventType.UPDATE, CanalEntry.EventType.INSERT} // 监听类型 ) public void onEventCustomUpdate(CanalEntry.EventType eventType, CanalEntry.RowData rowData) { for (CanalEntry.Column column : rowData.getBeforeColumnsList()) { log.info("自定义操作前: 列名:" + column.getName() + "------ 变更的数据:" + column.getValue()); } for (CanalEntry.Column column : rowData.getAfterColumnsList()) { log.info("自定义操作后: 列名:" + column.getName() + "------ 变更的数据:" + column.getValue()); } } } ### 2.3.4 新建启动类 ### import com.xpand.starter.canal.annotation.EnableCanalClient; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; /** * Canal微服务,监听数据库变化并响应 */ @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) @EnableEurekaClient @EnableCanalClient public class CanalApplication { public static void main(String[] args) { SpringApplication.run(CanalApplication.class, args); } } ### 2.3.5 编写微服务配置文件 ### ![20200530174246921.png][] # 192.168.47.142 为安装了redis、canal的远端服务器 server: port: 18082 spring: application: name: canal redis: host: 192.168.47.142 port: 6379 eureka: client: service-url: defaultZone: http://127.0.0.1:7001/eureka instance: prefer-ip-address: true feign: hystrix: enabled: true hystrix: command: default: execution: timeout: # 若enabled设置为false,则请求超时交给ribbon控制 enabled: true isolation: strategy: SEMAPHORE canal: client: instances: example: host: 192.168.47.142 port: 11111 ## 2.4 测试 ## 项目运行后,修改数据库即可看到控制台打印出修改的内容了。 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDE2MzMx_size_16_color_FFFFFF_t_70 5][] [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDE2MzMx_size_16_color_FFFFFF_t_70]: https://img-blog.csdnimg.cn/20200529225114113.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDE2MzMx,size_16,color_FFFFFF,t_70 [20200529231103984.png]: https://img-blog.csdnimg.cn/20200529231103984.png [20200529233144653.png]: https://img-blog.csdnimg.cn/20200529233144653.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDE2MzMx_size_16_color_FFFFFF_t_70 1]: https://img-blog.csdnimg.cn/20200529233312522.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDE2MzMx,size_16,color_FFFFFF,t_70 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDE2MzMx_size_16_color_FFFFFF_t_70 2]: https://img-blog.csdnimg.cn/20200529233637741.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDE2MzMx,size_16,color_FFFFFF,t_70 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDE2MzMx_size_16_color_FFFFFF_t_70 3]: https://img-blog.csdnimg.cn/20200529233717906.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDE2MzMx,size_16,color_FFFFFF,t_70 [20200529234029437.png]: https://img-blog.csdnimg.cn/20200529234029437.png [2020052923421255.png]: https://img-blog.csdnimg.cn/2020052923421255.png [https_github.com_chenqian56131_spring-boot-starter-canal]: https://github.com/chenqian56131/spring-boot-starter-canal [20200530001305881.png]: https://img-blog.csdnimg.cn/20200530001305881.png [20200530001348395.png]: https://img-blog.csdnimg.cn/20200530001348395.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDE2MzMx_size_16_color_FFFFFF_t_70 4]: https://img-blog.csdnimg.cn/20200530174103822.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDE2MzMx,size_16,color_FFFFFF,t_70 [20200530174246921.png]: https://img-blog.csdnimg.cn/20200530174246921.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDE2MzMx_size_16_color_FFFFFF_t_70 5]: https://img-blog.csdnimg.cn/20200530174709347.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0NDE2MzMx,size_16,color_FFFFFF,t_70
相关 学习笔记 \ajax: 1、概念:异步的JavaScript 和 xml 1.1异步和同步:客户端和服务器端相互通信的基础上 \客户端必须等待服务器端的响应。在等待的期间客户 深藏阁楼爱情的钟/ 2022年10月29日 13:24/ 0 赞/ 261 阅读
相关 学习笔记 1、定义纯汇编的祼函数: void \_\_declspec(naked) \_\_stdcall NakeFunction() \{ > \_\_asm \{ > > ╰+攻爆jí腚メ/ 2022年09月23日 08:09/ 0 赞/ 292 阅读
相关 学习笔记 jQuery 中 字符串转成 Json 格式 //需要注意的是在Json字符串中不能出现单引号或者是字符串但不带双引号。 <script type="text/ 比眉伴天荒/ 2022年06月09日 07:14/ 0 赞/ 293 阅读
相关 【学习笔记】git学习笔记 使用git的好处 可以保存每个版本,只要在每个版本做完后进行上传 ![这里写图片描述][70] 可以异地读取更新 爱被打了一巴掌/ 2022年05月14日 09:10/ 0 赞/ 378 阅读
相关 学习笔记 我的第一天学习c\ 1、c\学习网址 [https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide 矫情吗;*/ 2022年05月08日 06:16/ 0 赞/ 298 阅读
相关 学习笔记 测试 ORM JPA EJB JPQL MOM JMS ORM 对象关系映射 英语:Object Relational M 爱被打了一巴掌/ 2022年02月16日 01:57/ 0 赞/ 377 阅读
相关 [笔记] Docker 学习笔记 1. 什么是 Docker > 官方文档:[链接][Link 1],中文文档:[链接][Link 2] Docker 属于 Linux 容器的一种封装,提供简单易用的容 缺乏、安全感/ 2021年11月27日 02:01/ 0 赞/ 556 阅读
相关 学习笔记 1、js如何将136分钟转化为几小时,几分钟 return (Math.floor(minutes/60) + "小时" + (minutes%60) + "分" 爱被打了一巴掌/ 2021年07月25日 23:46/ 0 赞/ 1024 阅读
还没有评论,来说两句吧...