SpringBoot 集成 JetCache-Alibaba 实现本地缓存

news2024/10/7 4:36:34

目录

  • 1、JetCache 简介
  • 2、JetCache 核心概念
  • 3、入门案例
    • 3.1、引入依赖
    • 3.2、修改配置文件
    • 3.3、添加配置扫描注解
    • 3.4、使用 JetCache
      • 3.4.1、基于注解实现缓存
        • 3.4.1.1、添加 `UserServiceImpl`:
        • 3.4.1.2、添加 `TestController`:
        • 3.4.1.1、`@Cached` 注解
        • 3.4.1.1.1、cacheType 属性
        • 3.4.1.2、`@CacheUpdate` 注解
        • 3.4.1.3、`@CacheInvalidate` 注解
      • 3.4.2、基于 `@CreateCache` 注解实现缓存
      • 3.4.3、基于 API 方式实现缓存
        • 3.4.3.1、添加一个配置类 `JetcacheConfig`:
        • 3.4.3.2、添加 `TestController`

1、JetCache 简介

官网地址
官方文档

JetCache 是由阿里巴巴开源的一款基于 Spring 和 Redis 的分布式缓存框架 ,提供统一的 API 和注解来简化缓存的使用。

JetCache 提供了比 Spring Cache更加强大的注解,可以原生的支持 TTL、两级缓存、分布式自动刷新,还提供了 Cache 接口用于手工缓存操作。 当前有四个实现,RedisCacheTairCache(此部分未在 github 开源)、CaffeineCache(in memory) 和一个简易的 LinkedHashMapCache (in memory),要添加新的实现也是非常简单的

它的特性:

  • 通过统一的 API 访问 Cache 系统
  • 通过注解实现声明式的方法缓存,支持 TTL 和两级缓存
  • 通过注解创建并配置 Cache 实例
  • 针对所有 Cache 实例和方法缓存的自动统计
  • Key 的生成策略和 Value 的序列化策略是可以配置的
  • 分布式缓存自动刷新,分布式锁 (2.2+)
  • 异步 Cache API (2.2+,使用 Redis 的 lettuce 客户端时)

2、JetCache 核心概念

  • 缓存抽象JetCache-Alibaba 提供了一个统一的缓存抽象层,这意味着你不需要直接和具体的缓存实现打交道。它为你封装好了底层的细节,你只需要通过它提供的 API 来操作缓存即可。这样一来,你更换缓存实现的时候,就不需要改动大量的代码了
  • 分布式缓存: 在分布式系统中,应用可能部署在多台机器上。这时候,如果每台机器都有自己的本地缓存,那数据就不一致了。JetCache-Alibaba 支持分布式缓存,它能确保多台机器上的缓存数据是一致的。这样,无论你的应用部署在哪里,都能读到正确的缓存数据
  • 缓存一致性: 缓存里的数据和数据库里的数据得保持一致。JetCache-Alibaba 提供了多种策略来确保缓存的一致性,比如缓存失效、缓存更新等。根据自己的业务场景来选择合适的策略
  • 降级策略: 有时候,缓存可能会失效或者出点什么问题。这时候,应用可不能直接崩溃。JetCache-Alibaba 提供了降级策略,当缓存不可用时,它会自动切换到数据库或者其他备份数据源,确保你的应用依然能够正常运行

3、入门案例

3.1、引入依赖

https://github.com/alibaba/jetcache/blob/master/docs/CN/GettingStarted.md

<dependency>
    <groupId>com.alicp.jetcache</groupId>
    <artifactId>jetcache-starter-redis</artifactId>
    <version>2.7.3</version>
</dependency>
<!-- jedis  -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>4.3.0</version>
</dependency>

这里使用了 Jedis 客户端连接 Redis

注意,如果启动出现 NoClassDefFoundError: redis/clients/util/PoolNoClassDefFoundError: redis/clients/jedis/UnifiedJedis 报错,说明 springboot 与 jetcache 版本不一致。如果使用的是jetcache2.7.x 版本,因为该版本中有 jedis 包的依赖,需要额外添加如下依赖,或者将 jetcache 版本将至 2.6.5 以下

3.2、修改配置文件

更详细的参数配置可参考官网说明:https://gitcode.com/gh_mirrors/je/jetcache/blob/master/docs/CN/Config.md

jetcache:
  # 统计间隔 0 表示不统计
  statIntervalMinutes: 15
  # 是否在缓存名称中包含 area。
  # jetcache-anno 把 cacheName 作为远程缓存 key 前缀,2.4.3 以前的版本总是把 areaName 加在 cacheName 中,因此 areaName 也出现在 key 前缀中。
  # 2.4.4以后可以配置,为了保持远程 key 兼容默认值为 true,但是新项目的话 false 更合理些,2.7 默认值已改为 false。
  areaInCacheName: false
  # 缓存类型。local 本地缓存;remote 远程缓存;local+remote 本地+远程缓存
  # 本地缓存:caffeine、linkedhashmap
  # 远程缓存:redis、tair
  local:
    # area:默认缓存配置。对应 @Cached 和 @CreateCache 的 area 属性
    default:
      # 本地缓存类型
      type: caffeine
      # key 转换器:fastjson、fastjson2、jackson
      # 仅当使用 @CreateCache 且缓存类型为 local 时可以指定为 none,此时通过 equals 方法来识别 key。方法缓存必须指定 keyConvertor
      keyConvertor: JACKSON
      # 每个缓存实例的最大元素的全局配置,仅 local 类型的缓存需要指定
      limit: 100
      # 缓存过期时间,单位毫秒
      expireAfterWriteInMillis: 100000
      # 指定多长时间没有访问,就让缓存失效,当前只有本地缓存支持  以毫秒为单位;0 表示不使用这个功能
      expireAfterAccessInMillis: 100000
  # 远程缓存配置
  remote:
    default:
      # 远程缓存类型
      type: redis
      keyConvertor: JACKSON
      # 配置远程缓存的广播通道,通常用于分布式环境中实现缓存同步
      #broadcastChannel: myBroadcastChannel
      # 2.7+可选java/kryo/kryo5;2.6-可选java/kryo
      valueEncoder: java
      # 2.7+可选java/kryo/kryo5;2.6-可选java/kryo
      valueDecoder: java
      # redis 线程池
      poolConfig:
        minIdle: 5
        maxIdle: 20
        maxTotal: 50
      host: 127.0.0.1
      port: 6379

3.3、添加配置扫描注解

启动类添加注解 @EnableCreateCacheAnnotation,开启缓存;添加@EnableMethodCache(basePackages = "com.zzc") 注解,配置缓存方法扫描路径

@EnableCreateCacheAnnotation
@EnableMethodCache(basePackages = "com.zzc")
@SpringBootApplication
public class Test2Application {

    public static void main(String[] args) {
        SpringApplication.run(Test2Application.class, args);
    }
}

3.4、使用 JetCache

3.4.1、基于注解实现缓存

https://gitcode.com/gh_mirrors/je/jetcache/blob/master/docs/CN/MethodCache.md

JetCache 方法缓存和 Spring Cache比较类似,它原生提供了 TTL 支持,以保证最终一致,并且支持二级缓存。JetCache2.4 以后支持基于注解的缓存更新和删除。

在 Spring 环境下,使用 @Cached 注解可以为一个方法添加缓存,@CacheUpdate 用于更新缓存,@CacheInvalidate用于移除缓存元素。注解可以加在接口上也可以加在类上,加注解的类必须是一个Spring Bean。

3.4.1.1、添加 UserServiceImpl
@Slf4j
@Service
public class UserServiceImpl {

    // 模拟数据库数据
    private Map<Integer, User> userMap = new HashMap<>();

    @Cached(name = "userCache:", key = "#user.id", expire = 3600, timeUnit = TimeUnit.SECONDS, cacheType = CacheType.LOCAL)
    public User add(User user) {
        log.info("add");
        userMap.put(user.getId(), user);
        return user;
    }

    @Cached(name = "userCache:", key = "#id", expire = 3600, timeUnit = TimeUnit.SECONDS, cacheType = CacheType.LOCAL)
    public User get(Integer id) {
        log.info("get");
        return userMap.get(id);
    }

    @CacheUpdate(name = "userCache:", key = "#user.id", value = "#user")
    public User update(User user) {
        log.info("update");
        userMap.put(user.getId(), user);
        return user;
    }

    @CacheInvalidate(name = "userCache:", key = "#id")
    public void delete(Integer id) {
        log.info("delete");
        userMap.remove(id);
    }

}
3.4.1.2、添加 TestController
@RestController
public class TestController {

    @Autowired
    private UserServiceImpl userServiceImpl;

    @PostMapping
    public String add(@RequestBody User user) {
        userServiceImpl.add(user);
        return "add";
    }

    @GetMapping("/{id}")
    public User get(@PathVariable Integer id) {
        User user = userServiceImpl.get(id);
        return user;
    }

    @PutMapping
    public String update(@RequestBody User user) {
        userServiceImpl.update(user);
        return "update";
    }

    @DeleteMapping("/{id}")
    public String delete(@PathVariable Integer id) {
        userServiceImpl.delete(id);
        return "delete";
    }

}

@CacheUpdate@CacheInvalidate 的 name 和 area 属性必须和 @Cached` 相同,name 属性还会用做 cache 的 key 前缀

3.4.1.1、@Cached 注解

@Cached 注解的属性如下:

属性默认值说明
area“default”如果在配置中配置了多个缓存 area,在这里指定使用哪个 area
name指定缓存的唯一名称,不是必须的,如果没有指定,会使用类名+方法名。name 会被用于远程缓存的 key 前缀。另外在统计中,一个简短有意义的名字会提高可读性。
key使用 SpEL 指定 key,如果没有指定会根据所有参数自动生成
expire超时时间。如果注解上没有定义,会使用全局配置,如果此时全局配置也没有定义,则为无穷大
timeUnitTimeUnit.SECONDS指定 expire 的单位
cacheTypeCacheType.REMOTE缓存的类型,包括 CacheType.REMOTE、CacheType.LOCAL、CacheType.BOTH。如果定义为 BOTH,会使用 LOCAL 和 REMOTE 组合成两级缓存
localLimit如果 cacheType 为 LOCAL 或 BOTH,这个参数指定本地缓存的最大元素数量,以控制内存占用。如果注解上没有定义,会使用全局配置,如果此时全局配置也没有定义,则为 100
localExpire仅当 cacheType 为 BOTH 时适用,为内存中的 Cache 指定一个不一样的超时时间,通常应该小于 expire
serialPolicy指定远程缓存的序列化方式。可选值为 SerialPolicy.JAVA 和 SerialPolicy.KRYO。如果注解上没有定义,会使用全局配置,如果此时全局配置也没有定义,则为 SerialPolicy.JAVA
keyConvertor指定 KEY 的转换方式,用于将复杂的 KEY 类型转换为缓存实现可以接受的类型,当前支持KeyConvertor.FASTJSON 和 KeyConvertor.NONE。NONE 表示不转换,FASTJSON 可以将复杂对象 KEY 转换成 String。如果注解上没有定义,会使用全局配置
enabledtrue是否激活缓存。例如某个 dao 方法上加缓存注解,由于某些调用场景下不能有缓存,所以可以设置 enabled 为 false,正常调用不会使用缓存,在需要的地方可使用 CacheContext.enableCache 在回调中激活缓存,缓存激活的标记在 ThreadLocal 上,该标记被设置后,所有 enable=false 的缓存都被激活
cacheNullValuefalse当方法返回值为null的时候是否要缓存
condition使用 SpEL 指定条件,如果表达式返回 true 的时候才去缓存中查询
postCondition使用 SpEL 指定条件,如果表达式返回 true 的时候才更新缓存,该评估在方法执行后进行,因此可以访问到 #result
3.4.1.1.1、cacheType 属性

可以指定本地缓存、远程缓存、本地缓存 + 远程缓存。

@Cached(name = "userCache:", key = "#user.id", expire = 3600, timeUnit = TimeUnit.SECONDS, cacheType = CacheType.REMOTE)
public User add(User user) {
    log.info("add");
    userMap.put(user.getId(), user);
    return user;
}

此时,User 需要实现 Serializable 接口

多级缓存的形式,会先从本地缓存获取数据,本地获取不到会从远程缓存获取;

3.4.1.2、@CacheUpdate 注解

@CacheUpdate 注解的属性如下:

属性默认值说明
area“default”如果在配置中配置了多个缓存 area,在这里指定使用哪个 area
name指定缓存的唯一名称,不是必须的,如果没有指定,会使用类名+方法名。name 会被用于远程缓存的 key 前缀。另外在统计中,一个简短有意义的名字会提高可读性。
key使用 SpEL 指定 key,如果没有指定会根据所有参数自动生成
value使用 SpEL 指定 value
condition使用 SpEL 指定条件,如果表达式返回 true 的时候才去缓存中查询
3.4.1.3、@CacheInvalidate 注解

@CacheInvalidate 注解的属性如下:

属性默认值说明
area“default”如果在配置中配置了多个缓存 area,在这里指定使用哪个 area
name指定缓存的唯一名称,不是必须的,如果没有指定,会使用类名+方法名。name 会被用于远程缓存的 key 前缀。另外在统计中,一个简短有意义的名字会提高可读性。
key使用 SpEL 指定 key,如果没有指定会根据所有参数自动生成
condition使用 SpEL 指定条件,如果表达式返回 true 的时候才去缓存中查询

使用 @CacheUpdate@CacheInvalidate 的时候,相关的缓存操作可能会失败(比如网络 IO 错误),所以指定缓存的超时时间是非常重要的

3.4.2、基于 @CreateCache 注解实现缓存

jetcache 2.7 版本 @CreateCache 注解已经废弃

3.4.3、基于 API 方式实现缓存

通过 CacheManager,2.7 版本才可使用

https://github.com/alibaba/jetcache/blob/master/docs/CN/CreateCache.md

使用 CacheManager 可以创建 Cache 实例,area 和 name 相同的情况下,它和 Cached 注解使用同一个 Cache 实例

3.4.3.1、添加一个配置类 JetcacheConfig
@Configuration
public class JetcacheConfig {

    @Autowired
    private CacheManager cacheManager;
    private Cache<Integer, Object> userCache;

    @PostConstruct
    public void init(){
        QuickConfig qc = QuickConfig.newBuilder("userCache:")
                .expire(Duration.ofSeconds(3600))
                .cacheType(CacheType.BOTH)
                // 本地缓存更新后,将在所有的节点中删除缓存,以保持强一致性
                .syncLocal(false)
                .build();
        userCache = cacheManager.getOrCreateCache(qc);
    }

    @Bean
    public Cache<Integer, Object> getUserCache(){
        return userCache;
    }
}
3.4.3.2、添加 TestController
@RestController
public class TestController {

    @Autowired
    private Cache<Integer, Object> userCache;

    @PostMapping
    public String add(@RequestBody User user) {
        userCache.put(user.getId(), user);
        return "add";
    }

    @GetMapping("/{id}")
    public User get(@PathVariable Integer id) {
        User user = (User) userCache.get(id);
        return user;
    }

    @PutMapping
    public String update(@RequestBody User user) {
        userCache.put(user.getId(), user);
        return "update";
    }

    @DeleteMapping("/{id}")
    public String delete(@PathVariable Integer id) {
        userCache.remove(id);
        return "delete";
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2193532.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++面试速通宝典——7

150. 数据库连接池的作用 数据库连接池的作用包括以下几个方面&#xff1a; 资源重用&#xff1a;连接池允许多个客户端共享有限的数据库连接&#xff0c;减少频繁创建和销毁连接的开销&#xff0c;从而提高资源的利用率。 统一的连接管理&#xff1a;连接池集中管理数据库连…

传感器模块编程实践(一)AS608指纹模块简介及驱动源码

文章目录 一.概要二.AS608模块主要技术指标三.AS608模块接线说明四.AS608模块通讯协议介绍五.AS608模块指纹录入与刷指纹流程六.STM32单片机与AS608模块指纹录入与刷指纹实验1.硬件准备2.软件工程3.软件主要代码4.实验效果 七.CubeMX工程源代码下载八.小结 一.概要 AS608 指纹…

打印机驱动安装教程-共享打印机修复工具-打印机扫描教程

金舟打印机驱动修复软件是驱动下载软件&#xff0c;无法解决打印机报错、打印异常、打印机无法连接等问题。 Part 1&#xff1a;打印机驱动安装教程 第一步&#xff1a;确定电脑上的打印机服务已启动 1.1右击桌面的“此电脑”然后点击“管理”。 1.2点击左侧任务栏中的“服务…

传奇GOM引擎架设好进游戏后提示请关闭非法外挂,重新登录,如何处理?

今天在架设一个GOM引擎的版本时&#xff0c;进游戏之后刚开始是弹出一个对话框&#xff0c;提示请关闭非法外挂&#xff0c;重新登录&#xff0c;我用的是绿盟登陆器&#xff0c;同时用的也是绿盟插件&#xff0c;刚开始我以为是绿盟登录器的问题&#xff0c;于是就换成原版gom…

推理攻击-Python案例

1、本文通过推理攻击的方式来估计训练集中每个类别的样本数量、某样本是否在训练集中。 2、一种简单的实现方法&#xff1a;用模型对训练数据标签进行拟合&#xff0c;拟合结果即推理为训练集中的情况。 3、了解这些案例可以帮助我们更好的保护数据隐私。 推理攻击&#xff08;…

华为最新业绩出炉!上半年营收4175亿元,同比增长34%!

华为2024年上半年经营业绩分析:稳健发展,符合预期 [中国,深圳,2024年8月29日] 今日,华为发布了其2024年上半年的经营业绩,整体表现稳健,结果符合预期。在复杂多变的全球市场环境下,华为凭借强大的创新能力和市场洞察力,实现了销售收入和净利润的显著增长。 上半年,华…

ubunut声卡配置 播放视频没有声音的解决方法 蓝牙问题

文章目录 &#x1f315;ubuntu22.04网页没有声音&#xff0c;声卡提示Dummy Output&#x1f319;方法一&#xff1a;&#xff08;亲测可行&#xff09;切换内核&#x1f319;方法二&#xff1a;&#xff08;推荐&#xff09;ubuntu22.04用pipewire替代pulseaudio⭐下载安装pipe…

Operational Concept(OpsCon)与Concept of Operations(ConOps)概念区分

Operational Concept(OpsCon)与Concept of Operations&#xff08;ConOps&#xff09;概念区分 在系统工程相关资料中会看到两个概念&#xff0c;一个是Operational Concept&#xff08;OpsCon&#xff09;&#xff0c;另一个是Concept of Operations&#xff08;ConOps&#x…

车载诊断协议DoIP系列 —— DoIP APP 应用层(AL)

车载诊断协议DoIP系列 —— DoIP APP 应用层(AL) 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师(Wechat:gongkenan2013)。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 本就是小人物,输了就是输了,不要在意别人怎么看自己。江湖一碗茶,喝…

十四、深入理解Mysql索引底层数据结构与算法

文章目录 一、索引的本质1、索引是帮助MySQL高效获取数据的排好序的数据结构2、索引的数据结构3、数据结构可视化网站 二、常见数据结构介绍1、B-Tree2、BTree&#xff08;B-Tree变种&#xff09;3、Hash结构 三、存储引擎的索引实现1、MyISAM存储引擎索引实现MyISAM索引文件和…

数理统计(第1章第2节:一些常用的抽样分布)

目录 统计量的概率分布称为“抽样分布” 1. 正态母体的子样平均数的抽样分布 正态分布 2. 卡方分布 3. t分布 4. F分布 5. 例题 6. 总结 统计量的概率分布称为“抽样分布” 1. 正态母体的子样平均数的抽样分布 正态分布 若随机变量X的概率密度为&#xff1a; 则称X服…

[C#]winform部署官方yolov11-obb旋转框检测的onnx模型

【官方框架地址】 https://github.com/ultralytics/ultralytics 【算法介绍】 Yolov11-obb&#xff08;You Only Look Once version 8 with Oriented Bounding Boxes&#xff09;是一种先进的对象检测算法&#xff0c;它在传统的Yolov3和Yolov4基础上进行了优化&#xff0c;加…

Python 如何使用 scikit-learn 进行模型训练

如何使用 scikit-learn 进行模型训练 一、简介 在现代的数据科学和机器学习领域&#xff0c;Python 已经成为最流行的编程语言之一。而其中最流行的机器学习库之一就是 scikit-learn。scikit-learn 提供了许多方便的工具和函数来实现常见的机器学习任务&#xff0c;包括数据预…

spi hal库 正点原子版

这个图 是了解一下 spi就是cs片选&#xff0c;clk时钟&#xff0c;miso主机输入从机输出&#xff0c;mosi主机输出从机输入&#xff0c;这四根线 spi最主要就是极性和相位的选择&#xff0c;spi是边沿采集&#xff0c;和iic的电平采集不一样&#xff0c;所以需要通过极性和相位…

SpringBoot 多元化配置(正则表达式,配置文件优先级)

1.配置绑定 所谓“配置绑定”就是把配置文件中的值与 JavaBean 中对应的属性进行绑定。通常&#xff0c;我们会把一些配置信息&#xff08;例如&#xff0c;数据库配置&#xff09;放在配置文件中&#xff0c;然后通过 Java 代码去读取该配置文件&#xff0c;并且把配置文件中…

【持续更新中】MMDetection3训练自己的数据集常见报错解决

博主近来跑自己数据集需要对比试验&#xff0c;故选择了MMDetection3这一算法整合详细的框架&#xff0c;遇到了较多问题在此处留作记录&#xff0c;若你也有相应的问题可以在评论区提出与解决方法。会持续更新&#xff0c;同时欢迎批评指正。 0.ModuleNotFoundError: No modu…

从博士到院士,国家级人才荣誉称号一览

在中国的科技界&#xff0c;两院院士代表着学术成就的巅峰荣誉&#xff0c;享有终身荣耀&#xff0c;并且是科研人员梦寐以求的最高职业荣誉。除了院士头衔之外&#xff0c;国家和各部委还设立了一系列针对不同年龄段学术人才的国家级荣誉称号体系&#xff0c;旨在表彰各类优秀…

8.9K Star,开源自托管离线翻译引擎

Hi&#xff0c;骚年&#xff0c;我是大 G&#xff0c;公众号「GitHub 指北」会推荐 GitHub 上有趣有用的项目&#xff0c;一分钟 get 一个优秀的开源项目&#xff0c;挖掘开源的价值&#xff0c;欢迎关注。 在全球化的今天&#xff0c;跨语言交流已成为日常需求&#xff0c;然…

U3D游戏开发之中剧情系统的制作

今天我们来揭秘带有人物选项的剧情系统该如何制作。 半年前我接到了一个剧情系统的需求&#xff0c;本着能抄代码绝不自己动手的想法在B站上面找现成系统&#xff0c;大概看了一些内容&#xff0c;发现比较繁琐就直接自己动手写了。 目录 1 需求分析 2 梳理代码逻辑 3 代码书…

k8s 中存储之 NFS 卷

目录 1 NFS 卷的介绍 2 NFS 卷的实践操作 2.1 部署一台 NFS 共享主机 2.2 在所有k8s节点中安装nfs-utils 2.3 部署nfs卷 2.3.1 生成 pod 清单文件 2.3.2 修改 pod 清单文件增加 实现 NFS卷 挂载的 参数 2.3.3 声明签单文件并查看是否创建成功 2.3.4 在 NFS 服务器 创建默认发布…