微服务框架 SpringCloud微服务架构 多级缓存 49 缓存同步 49.3 监听Canal

本文详细介绍如何在SpringCloud项目中利用Canal实现数据变更监听,并通过Redis进行多级缓存同步,提升应用性能。涉及的技术包括Canal客户端、Item实体类映射、RedisHandler和ItemHandler处理逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

微服务框架

【SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】

多级缓存

49 缓存同步

49.3 监听Canal
49.3.1 Canal 客户端

Canal提供了各种语言的客户端,当Canal监听到binlog变化时,会通知Canal的客户端。

在这里插入图片描述

Canal提供了各种语言的客户端,当Canal监听到binlog变化时,会通知Canal的客户端。不过这里我们会使用GitHub上的第三方开源的canal-starter。

地址:https://github.com/NormanGyllenhaal/canal-client

在这里插入图片描述

好家伙,纯Java 编写

引入依赖:

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

在这里插入图片描述

OK

编写配置:

canal:
  destination: heima
  server: 1.13.92.88:11111

在这里插入图片描述

OK

【编写监听器】

在这里插入图片描述

Canal推送给canal-client的是被修改的这一行数据(row),而我们引入的canal-client则会帮我们把行数据封装到Item实体类中。

这个过程中需要知道数据库与实体的映射关系,要用到JPA的几个注解:

在这里插入图片描述

修改实体类

package com.heima.item.pojo;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;

import java.util.Date;

@Data
@TableName("tb_item")
public class Item {
    @TableId(type = IdType.AUTO)
    @Id
    private Long id;//商品id
    private String name;//商品名称
    private String title;//商品标题
    private Long price;//价格(分)
    private String image;//商品图片
    private String category;//分类名称
    private String brand;//品牌名称
    private String spec;//规格
    private Integer status;//商品状态 1-正常,2-下架
    private Date createTime;//创建时间
    private Date updateTime;//更新时间
    @TableField(exist = false)
    @Transient
    private Integer stock;
    @TableField(exist = false)
    @Transient
    private Integer sold;
}

修改RedisHandler,定义方法

// 新增
public void saveItem(Item item){

    try {
        String json = MAPPER.writeValueAsString(item);
        redisTemplate.opsForValue().set("item:id:" + item.getId(),json);
    } catch (JsonProcessingException e) {
        throw new RuntimeException(e);
    }

}

//删除
public void deleteItemById(Long id){
    redisTemplate.delete("item:id:" + id);
    
}

在这里插入图片描述

编写handler

package com.heima.item.canal;

import com.github.benmanes.caffeine.cache.Cache;
import com.heima.item.config.RedisHandler;
import com.heima.item.pojo.Item;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import top.javatool.canal.client.annotation.CanalTable;
import top.javatool.canal.client.handler.EntryHandler;

/**
 * ClassName: ItemHandler
 * date: 2022/11/8 20:51
 *
 * @author DingJiaxiong
 */

@CanalTable("tb_item")
@Component
public class ItemHandler implements EntryHandler<Item> {

    @Autowired
    private RedisHandler redisHandler;

    @Autowired
    private Cache<Long, Item> itemCache;

    @Override
    public void insert(Item item) {
        //写数据到JVM 进程缓存
        itemCache.put(item.getId(), item);
        //写数据到Redis
        redisHandler.saveItem(item);

    }

    @Override
    public void update(Item before, Item after) {

        //写数据到JVM 进程缓存
        itemCache.put(after.getId(), after);
        //写数据到Redis
        redisHandler.saveItem(after);

    }

    @Override
    public void delete(Item item) {
        //删除数据到JVM 进程缓存
        itemCache.invalidate(item.getId());
        //删除数据到Redis
        redisHandler.deleteItemById(item.getId());
    }
}

OK

重启服务

在这里插入图片描述

可以看到,它一直在和Canal 建立连接

OK, 我先把它打包 到服务器上跑起来先

在这里插入图片描述

OK

在这里插入图片描述

它也是一直在输出日志

在这里插入图片描述

开个端口

在这里插入图片描述

好家伙,我说怎么没数据,这写死 了 …

在这里插入图片描述

OK

拿到了,服务器上就要分别打两个包 了

就在本地操作吧,修改第一个商品的信息

在这里插入图片描述

直接确定

在这里插入图片描述

更新成功

查看IDEA 控制台日志

在这里插入图片描述

而且现在我再直接让 它去缓存拿,没问题

在这里插入图片描述

其实这儿逻辑有点问题,笔者还没有将项目部署好

在这里插入图片描述

后面弄好了

在这里插入图片描述

直接确定,

查看Redis 数据

在这里插入图片描述

没有一点毛病。就是请求地址写死了 不太好

在这里插入图片描述

OK,Redis 确实已经改了

刚刚不明显,我再来一个

在这里插入图片描述

我直接改成200 寸

在这里插入图片描述

直接查看Redis 缓存

在这里插入图片描述

非常明显,OK这就是缓存同步的 实现【但是吧,这样好像并没有改Nginx的本地缓存,虽然它会自己去拿】

【多级缓存总结】

在这里插入图片描述

OK,多级缓存就这样吧【黑马牛逼!!!!!!!】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

祝我天天开心,平安健康

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值