SpringBoot整合Canal:实现MySQL数据实时同步的终极解决方案

微服务架构盛行的今天,数据一致性成为了一个关键挑战。当业务数据在MySQL中发生变化时,如何实时同步到其他服务或缓存中?阿里巴巴开源的Canal组件为我们提供了完美的解决方案。今天,我将带你深入探索SpringBoot整合Canal的技术内幕,让你轻松掌握这一核心技术。

什么是Canal?

Canal是阿里巴巴开源的一个基于MySQL数据库增量日志解析的组件,它模拟MySQL主从复制的交互协议,伪装成MySQL的从节点,向MySQL主节点发送dump协议,获取到MySQL的二进制日志(binlog)后,再解析为便于理解和使用的数据格式。

项目架构中的Canal应用

在我们的SpringCloud微服务项目中,Canal扮演着数据同步中枢的角色。通过监听MySQL的binlog,实时捕获数据变更事件,并将这些变更推送到需要的服务中,实现数据的最终一致性。

实战:SpringBoot整合Canal(文末附代码链接)

1. 环境准备

首先,确保MySQL已开启binlog功能,并设置为ROW模式

-- 查看binlog配置

SHOW VARIABLES LIKE '%log_bin%';

SHOW VARIABLES LIKE 'binlog_format';

-- 如果未开启,需在my.ini中添加以下配置

server-id=1

log-bin=/path_to_binlog/mysql-bin

binlog_format=ROW

max_binlog_size=100M

同时,创建Canal专用用户

CREATE USER 'canal'@'%' IDENTIFIED BY 'canal';

GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';

FLUSH PRIVILEGES;

2. 服务端部署

下载并安装Canal Server

修改配置文件

conf/example/instance.properties

修改为你的MySQL连接信息

canal.instance.master.address=127.0.0.1:3306

canal.instance.dbUsername=canal

canal.instance.dbPassword=canal

修改配置文件conf/canal.properties

canal.serverMode = tcp

3. 客户端集成

在SpringBoot项目中添加依赖

<dependency>

<groupId>top.javatool</groupId>

<artifactId>canal-spring-boot-starter</artifactId>

<version>1.2.1-RELEASE</version>

</dependency>

4. 核心实现代码

创建数据变更处理器,监听特定表的数据变化:

@Slf4j

@Component

@CanalTable(value = "bu_user_info") // 对应的数据库表名

public class UserInfoHandler implements EntryHandler<UserInfo> {

@Autowired

private UserInfoCache userInfoCache;

@Override

public void delete(UserInfo t) {

log.info("删除操作: {}", JsonUtil.toJsonString(t));

userInfoCache.del(t.getId());

}

@Override

public void insert(UserInfo t) {

log.info("插入操作: {}", JsonUtil.toJsonString(t));

}

@Override

public void update(UserInfo before, UserInfo after) {

log.info("更新操作,更新前: {},更新后: {}", JsonUtil.toJsonString(before), JsonUtil.toJsonString(after));

userInfoCache.del(after.getId());

userInfoCache.getById(after.getId());

}

}

当用户信息表`bu_user_info`发生变更时,该处理器会自动捕获并处理相应的业务逻辑,如清除缓存、更新索引等。

5. 高级用法:消息队列集成

Mysql binlog -> Canal Server -> MQ(削峰填谷) -> Canal Client

为了提升系统性能和可靠性,我们还可以将Canal与消息队列集成,但

  1. top.javatool中canal沒有rabbitMQ、rocketMQ的实现,可阅读源码包

top.javatool.canal.client.spring.boot.autoconfigure,所以需要自己实现

  1. 项目中已整合消息驱动,包含rabbitMQ、rocketMQ的实现逻辑,所以只需要自定义实现

top.javatool.canal.client.handler.MessageHandler,即可以将MQ数据给到top.javatool的EntryHandler处理

  1. 新增自定义得我消息驱动实现:具体请看

@Configuration

@ConditionalOnProperty(value = CanalProperties.CANAL_MODE, havingValue = "messagedriven")

@Import(ThreadPoolAutoConfiguration.class)

public class MessagedrivenClientAutoConfiguration {

@Bean

public RowDataHandler<List<Map<String, String>>> rowDataHandler() {

return new MapRowDataHandlerImpl(new MapColumnModelFactory());

}

@Bean

public MessageHandler messageHandler(RowDataHandler<List<Map<String, String>>> rowDataHandler, List<EntryHandler> entryHandlers) {

return new SyncFlatMessageHandlerImpl(entryHandlers, rowDataHandler);

}

}

4.接口`EntryHandler<T>` 用法还是清晰简单的,所以将数据转发到EntryHandler处理(具体转发代码看文末代码链接)

如果用rabbitMQ

修改配置文件conf/canal.properties

canal.serverMode = rabbitMQ

rabbitmq.host = localhost:5672

rabbitmq.virtual.host = /

rabbitmq.exchange = fanout-canal

rabbitmq.username = guest

rabbitmq.password = guest

rabbitmq.deliveryMode =

如果用rocketMQ

1.配置文件conf/canal.properties

canal.serverMode = rocketMQ

rocketmq.producer.group = producer-group

rocketmq.enable.message.trace = false

rocketmq.customized.trace.topic =

rocketmq.namespace =

rocketmq.namesrv.addr = 127.0.0.1:9876

rocketmq.retry.times.when.send.failed = 0

rocketmq.vip.channel.enabled = false

rocketmq.tag =

2.修改配置文件

conf/example/instance.properties

canal.mq.topic=fanout-canal

这种模式下,Canal Server将变更数据发送到MQ,客户端从MQ消费数据,实现了削峰填谷。

实际应用场景

在我们的项目中,Canal主要用于以下场景

  1. 缓存同步:当数据库中的用户信息变更时,自动清除Redis中的缓存,确保数据一致性

  2. 搜索引擎同步:将商品信息变更实时同步到Elasticsearch,保证搜索结果的实时性

  3. 业务逻辑触发:当订单状态变更时,触发相应的业务流程,如发送通知、更新统计等

性能优化建议

  1. 处理器轻量化:确保处理器中的逻辑尽量简单,避免影响数据同步性能

  2. 批量处理:对于高并发场景,考虑批量处理数据变更事件

  3. 异常处理:完善的异常处理机制,防止因个别数据处理失败影响整体同步流程

结语

通过SpringBoot整合Canal,我们能够轻松实现MySQL数据的实时同步,大大简化了微服务架构下的数据一致性问题。这一技术方案已经在我们的生产环境中稳定运行,为业务的快速发展提供了强有力的技术支撑。

掌握Canal技术,不仅能提升你的架构设计能力,更能在实际工作中解决复杂的数据同步难题。赶紧在你的项目中尝试应用吧!

代码看这里

gitee:https://gitee.com/jq_di/springcloud-template

相关推荐
fanruitian2 小时前
SpringBoot 集成retrofit httpclient
java·spring boot·retrofit
Henry Zhu12311 小时前
操作系统原理详解(二):操作系统存储管理
系统架构
weixin_4250230013 小时前
Spring Boot + MyBatis Plus JOIN 分页多表查询项目文档
spring boot·后端·mybatis
肉丸滚球14 小时前
飞算 JavaAI 转 SpringBoot 项目沉浸式体验:高效开发在线图书借阅平台
java·spring boot·后端
叫我阿柒啊14 小时前
从Java全栈到前端框架:一场真实的技术面试对话
java·vue.js·spring boot·微服务·typescript·前端开发·后端开发
Kiyra15 小时前
阿里云 OSS + STS:安全的文件上传方案
网络·人工智能·安全·阿里云·系统架构·云计算·json
泉城老铁16 小时前
目前开源架构需要注意的安全问题
spring boot·后端
一 乐16 小时前
健身房预约|基于springboot + vue健身房预约小程序系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·学习·小程序
JIngJaneIL18 小时前
基于java+ vue家庭理财管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot