SpringBoot + RabbitMQ + canal实现缓存更新操作

之前已经分享了一篇关于springboot + canal实现缓存更新的功能,但这种方案存在缺陷,当项目属于微服务架构时,一个服务可能有多个实例,即使多个实例都在监听canal的消息,但是只有一个实例能够消费该消息以此更新缓存,针对只是Redis做缓存的情况下没有问题,但是多级缓存Caffeine+Redis就有问题了,只有一个服务实例能够更新本地的Caffeine缓存,其他服务实例就无法同步更新。因此我想到可以RabbitMQ实现多服务实例的缓存同步更新操作。而canal本身就可以与RabbitMQ联合使用。

在Linux服务器上利用docker部署MySQL和RabbitMQ后,再部署canal,这次部署和之前有差异。

首先启动容器:

[root@iZ2vc97qcawcm6uqblda2fZ ~]# docker run -d canal/canal-server:v1.1.5
ddcce88c2050213f584849704ddb9401f6a8be1a923b1987f49729ea558e3a31

然后从容器中拷贝配置文件

[root@iZ2vc97qcawcm6uqblda2fZ canal]# docker cp ddcce88c2050:/home/admin/canal-server/conf/canal.properties ./conf/
docker cp ddcce88c2050:/home/admin/canal-server/conf/example/instance.properties ./conf/

修改canal.properties配置文件信息:


##################################################
######### 		    RabbitMQ	     #############
##################################################
#不能加上端口号
rabbitmq.host =47.108.105.49               
rabbitmq.virtual.host =/
rabbitmq.exchange =canal.exchange
rabbitmq.username =guest
rabbitmq.password =guest
rabbitmq.deliveryMode =fanout

修改instance.properties配置文件:

#myqsl主库地址
canal.instance.master.address=47.108.105.49:3306

#mysql的binlog文件名
canal.instance.master.journal.name=mysql-bin.000006

#正则表达式过滤需要监听的数据库
canal.instance.filter.regex=recl\\..*

重启canal-server:

​
[root@iZ2vc97qcawcm6uqblda2fZ canal]# docker run -d \
> -v /docker/canal/conf/instance.properties:/home/admin/canal-server/conf/example/instance.properties \
> -v /docker/canal/conf/canal.properties:/home/admin/canal-server/conf/canal.properties \
> -p 11111:11111 \
> --name canal \
> canal/canal-server:v1.1.5
303291f6de8d7b6b77928e2aece00e52573b199f90c5000ff3102b72c2736268

​

创建springboot项目,引入rabbitMQ起步依赖:

        <!-- RabbitMQ -->
        <dependency>

            <groupId>org.springframework.boot</groupId>

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

        </dependency>

application.properties中的配置信息:

# RabbitMQ配置
spring.rabbitmq.host=47.108.105.49
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.virtual-host=/
spring.rabbitmq.listener.direct.prefetch=1

创建canal消息监听类:

package com.ren.fm.listener;

import com.alibaba.fastjson.JSON;
import com.rabbitmq.client.Channel;
import com.ren.fm.constant.CachePrefix;
import com.ren.utils.canal.CanalBean;
import com.ren.utils.canal.CanalType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;

/**
 * @ClassName: CanalMQListener
 * @Description: TODO
 * @Author: RZY
 * @DATE: 2022/7/17 9:13
 * @Version: v1.0
 */

@Component
@Slf4j
public class CanalMQListener {

    @Autowired
    CachePrefix cachePrefix;

    @RabbitListener(queues = "canal.queue.fm.8001")
    public void CanalMessageHandler(Message message, Channel channel) {
        //获取消息体内容
        CanalBean canalBean = null;
        try {
            //序列化消息体
            canalBean = JSON.parseObject(new String(message.getBody(), StandardCharsets.UTF_8), CanalBean.class);
            log.info("来自队列 {} 的消息", 8001);
            log.info("收到canal消息: {}", canalBean);
            String tableName = canalBean.getTable();
            if(CachePrefix.isContainsTableName(tableName) && !canalBean.isDdl()) {
                //当为UPDATE时,更新缓存
                if(canalBean.getType().equals(CanalType.UPDATE)) cachePrefix.updateCache(tableName, canalBean);
                //当为DELETE时,删除缓存
                if(canalBean.getType().equals(CanalType.DELETE)) cachePrefix.deleteCache(tableName, canalBean);
            }
        } catch (Exception e) {
            log.info("canal消息处理失败: {}", canalBean);
            throw new RuntimeException(e);
        }

    }
}

创建交换机和相关队列:

 启动项目测试:

①修改数据库中的某条记录

 ②查看RabbitMQ控制台(收到了日志信息):

 

 ③启动springboot项目(缓存更新成功):

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值