微服务框架
【SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】
多级缓存
文章目录
- 微服务框架
- 多级缓存
- 49 缓存同步
- 49.3 监听Canal
- 49.3.1 Canal 客户端
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,多级缓存就这样吧【黑马牛逼!!!!!!!】