Spring Boot整合Canal实战:Deployer与Adapter详细配置

1,226 阅读3分钟

Spring Boot整合Canal实战:从零到互联网级同步方案


一、Canal是啥?能干啥?

Canal,名字听着像“管道”,其实就是阿里开源的一个工具,专门盯着MySQL的增量日志(binlog)干活。通俗点讲,它把自己伪装成MySQL的从库,实时把主库的binlog抓过来,拆解成数据变更的事件(比如新增、修改、删除),然后推给下游系统用。这玩意儿就像是数据库和业务之间的“实时快递员”,能帮你干不少事,比如更新缓存、算统计数据、发通知啥的。

Canal咋实现的?
说白了,它靠的是MySQL的binlog。要让Canal跑起来,MySQL得满足两个条件:

  1. binlog得开着,格式还得是ROW(记录最全的那种)。
  2. 得给Canal整一个专用账号,权限得有REPLICATION SLAVEREPLICATION CLIENT

Linux上咋配MySQL?
直接上命令,别记错:

# 编辑my.cnf  
[mysqld]  
log-bin=mysql-bin  # 开binlog  
binlog-format=ROW  # 必须是ROW,别写错  
server-id=1        # 随便填个独一无二的ID,别撞车就行  

# 建个Canal用户  
mysql> CREATE USER 'canal'@'%' IDENTIFIED BY 'canal';  
mysql> GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';  
mysql> FLUSH PRIVILEGES;  

二、Canal的两个主力:Deployer和Adapter

  1. Deployer(服务端)
    • 干啥的?连上MySQL,掏出binlog,解析完再丢给客户端。
    • 配置在哪?canal.properties管全局,instance.properties管具体实例(比如MySQL地址、账号)。

  2. Adapter(适配器)
    • 干啥的?把Deployer扔来的数据收拾收拾,变成业务能用的格式,比如塞进Kafka、更新Elasticsearch。
    • 亮点?支持插拔式,想咋整就咋整。


三、Spring Boot咋接Canal?

第一步:加依赖
现在社区里挺火的Canal客户端是canal-spring-boot-starter,直接用这个:

<dependency>  
    <groupId>top.javatool</groupId>  
    <artifactId>canal-spring-boot-starter</artifactId>  
    <version>1.1.6</version>  
</dependency>  

第二步:配application.yml
简单点写,够用就行:

canal:  
  server: 192.168.1.100:11111  # Canal Deployer的地址  
  destination: example         # 实例名,跟Deployer那边对上  
  filter: .*\\..*              # 先监听所有表,后面再改细点  
  batch-size: 1000             # 一次拉多少条  
  retry: 3                     # 拉失败再试几次  

第三步:上代码
• 核心活儿:写个类实现EntryHandler<T>,监听表的增删改。
• 注解:@CanalTable("user")指定监听哪张表。

@CanalTable("user")  
@Component  
public class UserCanalHandler implements EntryHandler<User> {  

    // 新增  
    @Override  
    public void insert(User user) {  
        log.info("新增了个用户: {}", user);  
        // 比如更新缓存,或者发条消息  
    }  

    // 更新  
    @Override  
    public void update(User before, User after) {  
        log.info("用户数据变了: 之前={}, 现在={}", before, after);  
    }  

    // 删除  
    @Override  
    public void delete(User user) {  
        log.info("删了个用户: {}", user);  
    }  
}  

配置类咋弄?
• 加个@EnableCanalClient开客户端。
• 想高级点,可以自己写个CanalConfig,调调超时、线程啥的,看业务需要。


四、电商场景实战:订单状态同步

场景:用户下单后,订单状态从“待付款”变成“已支付”,再到“已发货”,得实时同步到:

  1. 前端页面进度条
  2. 库存系统解锁库存
  3. 风控盯着有没有猫腻

咋测?

  1. 本地起个Canal Deployer,连上测试库。
  2. Spring Boot盯着order表。
  3. 手动改数据库订单状态,看日志有没有动静。
  4. 再整条MQ消息打到控制台,假装通知下游。

五、从简单到牛逼:优化思路

简单方案的毛病
监听太粗filter: .*\\..*啥都听,机器扛不住。
同步卡壳:直接在insert/update里干活,Canal消费慢得像乌龟。
挂了咋办:网络一抖,数据丢了咋整?

咋优化?

  1. 听重点:改成只听关键表(比如filter: db1.order,db2.inventory)。
  2. 异步搞定:变更丢到MQ(比如Kafka),下游慢慢吃。
  3. 高可用
    • Canal Server搞集群,Zookeeper管着谁干活。
    • 客户端记个消费位点(Redis存binlog offset),别丢数据。

跟大厂学
数据管道:Canal → Kafka → 业务服务,解耦还抗压。
分布式适配:Adapter也搞集群,负载均衡跑起来。


六、还能咋玩?

搭Elasticsearch:数据一变,搜索索引跟着动。
追数据血缘:binlog还能看出字段咋变的。
灰度开关:监听配置表,动态切功能。