2.Spring Boot中集成Guava Cache或者Caffeine

一、在Spring Boot(1.x版本)中集成Guava Cache

  • 注意: Spring Boot 2.x+用户:优先使用Caffeine,性能更优且维护活跃。

1. 添加依赖

pom.xml中添加Guava依赖:

<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>31.0.1-jre</version> <!-- 使用最新版本 -->
</dependency>

2. 启用缓存支持

在启动类上添加@EnableCaching注解:

@SpringBootApplication
@EnableCaching
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}

3. 配置Guava缓存管理器

创建配置类定义CacheManager Bean:

@Configuration
public class CacheConfig {@Beanpublic CacheManager cacheManager() {GuavaCacheManager cacheManager = new GuavaCacheManager();cacheManager.setCacheBuilder(CacheBuilder.newBuilder().expireAfterWrite(10, TimeUnit.MINUTES) // 写入10分钟后过期.maximumSize(100) // 最大缓存数量.recordStats()); // 开启统计信息return cacheManager;}
}

4. 使用缓存注解

在Service层使用@Cacheable@CacheEvict等注解:

@Service
public class UserService {// 缓存查询结果,key为id@Cacheable(value = "USER_CACHE", key = "#id")public User getUserById(Long id) {return userRepository.findById(id).orElse(null);}// 更新缓存@CachePut(value = "USER_CACHE", key = "#user.id")public User updateUser(User user) {return userRepository.save(user);}// 删除缓存@CacheEvict(value = "USER_CACHE", key = "#id")public void deleteUser(Long id) {// 删除用户逻辑userRepository.deleteById(id);}}

5. 验证缓存效果

编写测试类或调用接口验证缓存是否生效:

@SpringBootTest
public class UserServiceTest {@Autowiredprivate UserService userService;@Testpublic void testCache() {// 第一次调用,执行方法User user1 = userService.getUserById("123");// 第二次调用,从缓存获取User user2 = userService.getUserById("123");// 验证是否为同一对象(缓存生效)assertThat(user1).isSameAs(user2);}
}

高级配置

  • 多缓存配置:为不同缓存设置不同策略:

    @Bean
    public CacheManager cacheManager() {GuavaCacheManager cacheManager = new GuavaCacheManager();cacheManager.setCacheBuilder(CacheBuilder.newBuilder().expireAfterWrite(30, TimeUnit.MINUTES).maximumSize(500));cacheManager.setCacheBuilder("userCache", CacheBuilder.newBuilder().expireAfterWrite(10, TimeUnit.MINUTES).maximumSize(100));return cacheManager;
    }
    
  • 刷新策略:使用refreshAfterWrite定时刷新(需配合LoadingCache):

    CacheBuilder.newBuilder().refreshAfterWrite(5, TimeUnit.MINUTES).build(CacheLoader.from(key -> loadData(key)));
    
  • 统计信息:通过recordStats()启用统计,使用cache.getStatistics()获取命中率等信息。

常见问题

  1. 缓存未生效

    • 确保启动类有@EnableCaching
    • 检查方法是否为public(注解在私有方法上无效)。
  2. 配置未应用

    • 确认CacheManager Bean正确注册。
    • 检查缓存名称是否匹配@Cacheable(value = "cacheName")
  3. 内存溢出

    • 合理设置maximumSizeexpireAfterAccess/Write

通过以上步骤,即可在Spring Boot中高效使用Guava Cache实现本地缓存,提升应用性能。



二、Spring Boot 2.x及以上版本(推荐使用Caffeine)

在Spring Boot 2.x及以上版本中,Caffeine作为默认的本地缓存组件,取代了Guava Cache,提供了更高的性能和更灵活的配置。


1. 添加依赖

需引入spring-boot-starter-cachecaffeine依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency><groupId>com.github.ben-manes.caffeine</groupId><artifactId>caffeine</artifactId><version>3.1.8</version> <!-- 推荐使用最新版本 -->
</dependency>

2. 启用缓存支持

在启动类添加@EnableCaching注解:

@SpringBootApplication
@EnableCaching
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}

3. 配置Caffeine缓存

方式一:通过配置文件

application.yml中定义全局缓存参数:

spring:cache:type: caffeinecaffeine:spec: maximumSize=500,expireAfterWrite=600s,initialCapacity=100cache-names: userCache, productCache  # 定义缓存名称
  • 常用参数
    • maximumSize:最大缓存条目数
    • expireAfterWrite:写入后过期时间
    • initialCapacity:初始容量。
方式二:通过Java Config类

为不同缓存设置独立策略(推荐多缓存场景):

@Configuration
@EnableCaching
public class CacheConfig {public enum Caches {USER_CACHE(600, 1000),  // 有效期600秒,最大容量1000PRODUCT_CACHE(3600);private final int ttl;private final int maxSize;Caches(int ttl, int maxSize) {this.ttl = ttl;this.maxSize = maxSize;}public int getTtl() {return ttl;}public int getMaxSize() {return maxSize;}}@Beanpublic CacheManager cacheManager() {SimpleCacheManager manager = new SimpleCacheManager();List<CaffeineCache> caches = Arrays.stream(Caches.values()).map(c -> new CaffeineCache(c.name(), Caffeine.newBuilder().expireAfterWrite(c.getTtl(), TimeUnit.SECONDS).maximumSize(c.getMaxSize()).build())).collect(Collectors.toList());manager.setCaches(caches);return manager;}
}

此方式支持为每个缓存单独配置过期时间和容量。


4. 使用缓存注解

在Service层通过注解操作缓存:

@Service
public class UserService {// 缓存查询结果,key为id@Cacheable(value = "USER_CACHE", key = "#id")public User getUserById(Long id) {return userRepository.findById(id).orElse(null);}// 更新缓存@CachePut(value = "USER_CACHE", key = "#user.id")public User updateUser(User user) {return userRepository.save(user);}// 删除缓存@CacheEvict(value = "USER_CACHE", key = "#id")public void deleteUser(Long id) {userRepository.deleteById(id);}
}
  • 注解说明
    • @Cacheable:查询时优先从缓存读取
    • @CachePut:更新数据并刷新缓存
    • @CacheEvict:删除数据时移除缓存。

5. 高级配置

刷新策略(RefreshAfterWrite)

需定义CacheLoader以支持自动刷新:

@Bean
public CacheLoader<Object, Object> cacheLoader() {return new CacheLoader<>() {@Overridepublic Object load(Object key) {return loadDataFromDB(key);  // 初始加载数据}@Overridepublic Object reload(Object key, Object oldValue) {return oldValue;  // 刷新时保留旧值,异步加载新值}};
}

配置文件中需添加refreshAfterWrite=5s,并关联此Bean。

统计与监控

启用统计功能:

Caffeine.newBuilder().recordStats().build();

通过cache.stats()获取命中率、回收数量等指标。


6. 验证缓存效果

通过测试类验证缓存是否生效:

@SpringBootTest
public class CacheTest {@Autowiredprivate UserService userService;@Testpublic void testCache() {User user1 = userService.getUserById(1L);  // 首次查询,存入缓存User user2 = userService.getUserById(1L);  // 二次查询,命中缓存assertThat(user1).isSameAs(user2);}
}

常见问题

  1. 缓存未命中

    • 检查方法是否为public(注解在私有方法无效)
    • 确认缓存名称与配置一致。
  2. 配置冲突

    • 避免同时配置maximumSizemaximumWeight
    • expireAfterWrite优先级高于expireAfterAccess

通过以上步骤,可在Spring Boot 2.x中高效集成Caffeine,实现高性能本地缓存,适用于高频访问但更新较少的数据场景(如配置信息、静态数据)。



三、Caffeine使用场景

Caffeine 作为高性能本地缓存库,适用于多种需要快速数据访问和高效内存管理的场景。以下是其主要使用场景及对应的技术优势分析:


1. 高并发请求缓存

  • 场景描述:适用于高频访问的接口或热点数据,例如用户信息查询、商品详情展示等。Caffeine 通过无锁并发设计和 Window TinyLFU 算法,显著提升缓存命中率,减少数据库压力。
  • 技术优势
    • 高性能:在高并发环境下,Caffeine 的吞吐量远超 Guava Cache,其分段锁机制避免了锁竞争问题。
    • 高命中率:Window TinyLFU 算法结合 LRU 和 LFU 优点,有效保留高频访问数据,命中率比 Guava 提升 10%~20%。
  • 典型应用:Web 应用的 API 接口缓存,如电商平台的商品详情页。

2. 数据库查询缓存

  • 场景描述:用于缓存频繁查询的数据库结果,如用户常用配置、热门商品库存等,减少重复数据库访问。
  • 技术优势
    • 自动过期策略:支持 expireAfterWrite(写入后过期)和 expireAfterAccess(访问后过期),防止数据过时。
    • 内存管理:通过 maximumSize 限制缓存条目数,避免内存溢出,结合惰性删除和定时清理机制优化内存使用。
  • 典型应用:用户登录信息缓存、商品库存实时查询缓存。

3. 复杂计算结果缓存

  • 场景描述:缓存计算密集型操作的结果,如图像处理、大数据聚合分析等,避免重复计算消耗资源。
  • 技术优势
    • 异步加载:通过 AsyncLoadingCache 异步加载数据,减少主线程阻塞,提升系统响应速度。
    • 刷新机制:使用 refreshAfterWrite 定时刷新缓存,保证数据更新后的及时性,同时保留旧数据直至新数据加载完成。
  • 典型应用:推荐系统的实时计算结果缓存、图像处理后的缩略图缓存。

4. 多级缓存架构(L1缓存)

  • 场景描述:在分布式系统中作为一级本地缓存(L1),结合 Redis(L2)和数据库(L3)形成三级缓存,减少跨服务或跨节点的网络延迟。
  • 技术优势
    • 低延迟访问:本地内存访问速度极快,适合对延迟敏感的场景。
    • 灵活集成:通过 CacheLoaderWriter 接口,可无缝与 Redis 等外部缓存联动,实现数据回源和同步。
  • 典型应用:秒杀系统的库存缓存、分布式服务中的配置信息缓存。

5. 需要高灵活性和统计监控的场景

  • 场景描述:对缓存策略有定制化需求(如动态调整过期时间、监听缓存事件)或需监控缓存命中率的场景。
  • 技术优势
    • 灵活配置:支持基于大小、时间、引用等多种淘汰策略,并可自定义过期逻辑。
    • 统计功能:通过 recordStats() 启用统计,获取命中率、淘汰次数等指标,便于性能调优。
  • 典型应用:实时监控系统的缓存健康状态、需要动态调整缓存策略的业务场景。

注意事项

  1. 非分布式场景:Caffeine 仅适用于本地缓存,跨节点数据需结合 Redis 等分布式缓存。
  2. 内存限制:需根据应用内存合理设置 maximumSize 或权重,避免 OOM 问题。
  3. 数据一致性:本地缓存可能导致多实例间数据不一致,需通过过期时间或事件通知机制解决。

总结

Caffeine 凭借其高性能、高命中率和灵活的配置,成为高并发、低延迟场景下的首选本地缓存库。尤其适合作为一级缓存与 Redis 等组成多级缓存架构,或用于需要快速响应和复杂策略管理的业务场景。实际应用中需结合具体需求调整淘汰策略和内存配置,以最大化其优势。

更多用法:

SpringBoot:第五篇 集成Guava(本地缓存+分布式缓存)

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

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

相关文章

黑马点评day02(缓存)

2、商户查询缓存 2.1 什么是缓存? 前言:什么是缓存? 就像自行车,越野车的避震器 举个例子:越野车,山地自行车,都拥有"避震器",防止车体加速后因惯性,在酷似"U"字母的地形上飞跃,硬着陆导致的损害,像个弹簧一样; 同样,实际开发中,系统也需要"避震…

头歌禁止复制怎么解除(简单版)

被头歌数据库作业禁止复制整神之后&#xff0c;主啵尝试网上各种解除方法&#xff0c;最后发现一个最简单且最快速的解除方法。 在浏览器中搜索万能复制插件 下载完成之后就可以随便复制粘贴啦 超简单 下载只需几秒

【无基础】小白解决Docker pull时报错:https://registry-1.docker.io/v2/

Docker Compose 启动失败问题解决方案 错误描述 执行 docker compose up -d 时出现以下错误&#xff1a; [] Running 9/9✘ api Error context canceled …

【数据结构】二叉树、堆

文章目录 二叉树的概念及结构定义特殊的二叉树核心性质存储方式 二叉树的链式存储前序遍历中序遍历后序遍历层序遍历 二叉树的顺序存储父子关系的推导堆&#xff08;heap&#xff09;堆的概念向上调整算法和向下调整算法向上调整算法向下调整算法 堆的创建堆的插入堆的删除 堆的…

Vue3响应式原理那些事

文章目录 1 响应式基础:Proxy 与 Reflect1.1 Proxy 代理拦截1.2 Reflect 确保 `this` 指向正确1.2.1 修正 `this` 指向问题1.2.2 统一的操作返回值1.3 与 Vue2 的对比2 依赖收集与触发机制2.1 全局依赖存储结构:WeakMap → Map → Set2.2 依赖收集触发时机2.3 依赖收集核心实…

精选10个好用的WordPress免费主题

10个好用的WordPress免费主题 1. Astra Astra 是全球最受欢迎的WordPress免费主题。它功能丰富&#xff0c;易于使用&#xff0c;SEO友好&#xff0c;是第一个安装量突破100万的非默认主题&#xff0c;并获得了5000多个五星好评。 它完美集成了Elementor、Beaver&#xff0c;…

【SaaS多租架构】数据隔离与性能平衡

SaaS多租户架构:数据隔离与性能平衡 一、技术背景及发展二、技术特点:数据隔离与性能优化的双核心三、技术细节:实现路径与关键技术四、实际案例分析五、未来发展趋势结语一、技术背景及发展 多租户架构是云计算与SaaS(软件即服务)模式的核心技术,其核心目标是通过共享基…

部署GM DC Monitor 一体化监控预警平台

1&#xff09;首先在官网下载镜像文件 广目&#xff08;北京&#xff09;软件有限公司广目&#xff08;北京&#xff09;软件有限公司https://www.gm-monitor.com/col.jsp?id1142&#xff09;其次进行部署安装&#xff0c;教程如下&#xff1a; 1. 基础环境要求 1) 系统&…

Webug4.0靶场通关笔记15- 第19关文件上传(畸形文件)

目录 第19关 文件上传(畸形文件) 1.打开靶场 2.源码分析 &#xff08;1&#xff09;客户端源码 &#xff08;2&#xff09;服务器源码 3.渗透实战 &#xff08;1&#xff09;构造脚本 &#xff08;2&#xff09;双写绕过 &#xff08;3&#xff09;访问脚本 本文通过《…

架构思维:构建高并发读服务_热点数据查询的架构设计与性能调优

文章目录 一、引言二、热点查询定义与场景三、主从复制——垂直扩容四、应用内前置缓存4.1 容量上限与淘汰策略4.2 延迟刷新&#xff1a;定期 vs. 实时4.3 逃逸流量控制4.4 热点发现&#xff1a;被动 vs. 主动 五、降级与限流兜底六、前端&#xff0f;接入层其他应对七、模拟压…

宝塔面板运行docker的jenkins

1.在宝塔面板装docker&#xff0c;以及jenkins 2.ip:端口访问jenkins 3.获取密钥&#xff08;点击日志&#xff09; 4.配置容器内的jdk和maven环境&#xff08;直接把jdk和maven文件夹放到jenkins容器映射的data文件下&#xff09; 点击容器-->管理-->数据存储卷--.把相…

C语言 ——— 函数

目录 函数是什么 库函数 学习使用 strcpy 库函数 自定义函数 写一个函数能找出两个整数中的最大值 写一个函数交换两个整型变量的内容 牛刀小试 写一个函数判断一个整数是否是素数 写一个函数判断某一年是否是闰年 写一个函数&#xff0c;实现一个整型有序数组的二分…

笔记本电脑升级计划(2017———2025)

ThinkPad T470 (2017) vs ThinkBook 16 (2025) 完整性能对比报告 一、核心硬件性能对比 1. CPU性能对比&#xff08;i5-7200U vs Ultra9-285H&#xff09; 参数i5-7200U (2017)Ultra9-285H (2025)提升百分比核心架构2核4线程 (Skylake)16核16线程 (6P8E2LPE)700%核心数制程工…

具身系列——PPO算法实现CartPole游戏(强化学习)

完整代码参考&#xff1a; https://gitee.com/chencib/ailib/blob/master/rl/ppo_cartpole.py 执行结果&#xff1a; 部分训练得分&#xff1a; (sd) D:\Dev\traditional_nn\feiai\test\rl>python ppo_cartpole_v2_succeed.py Ep: 0 | Reward: 23.0 | Running: 2…

Python项目源码60:电影院选票系统1.0(tkinter)

1.功能特点&#xff1a;通常选票系统应该允许用户选择电影、场次、座位&#xff0c;然后显示总价和生成票据。好的&#xff0c;我得先规划一下界面布局。 首先&#xff0c;应该有一个电影选择的列表&#xff0c;可能用下拉菜单Combobox来实现。然后场次时间&#xff0c;可能用…

【全队项目】智能学术海报生成系统PosterGenius--图片布局生成模型LayoutPrompt(2)

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;大模型实战训练营_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前…

Linux的时间同步服务器(附加详细实验案例)

一、计时方式的发展 1.古代计时方式​ 公元前约 2000 年&#xff1a;古埃及人利用光线留下的影子计时&#xff0c;他们修建高耸的大型方尖碑&#xff0c;通过追踪方尖碑影子的移动判断时间&#xff0c;这是早期利用自然现象计时的典型方式 。​商朝时期&#xff1a;人们开发并…

【无需docker】mac本地部署dify

环境安装准备 #安装 postgresql13 brew install postgresql13 #使用zsh的在全局添加postgresql命令集 echo export PATH"/usr/local/opt/postgresql13/bin:$PATH" >> ~/.zshrc # 使得zsh的配置修改生效 source ~/.zshrc # 启动postgresql brew services star…

(5)概述 QT 的元对象系统里的类的调用与联系,及访问接口

&#xff08;1&#xff09; QT 的元对象系统&#xff0c;这几个字大家都知道&#xff0c;那么 QT 的元对象系统里都包含哪些内容呢&#xff0c;其访问接口是如何呢&#xff1f; 从 QObject 类的实现里&#xff0c;从其数据成员里就可以看出来&#xff1a; QT 里父容器可以释放其…

打包 Python 项目为 Windows 可执行文件:高效部署指南

Hypackpy 是一款由白月黑羽开发的 Python 项目打包工具&#xff0c;它与 PyInstaller 等传统工具不同&#xff0c;通过直接打包解释器环境和项目代码&#xff0c;并允许开发者修改配置文件以排除不需要的内容&#xff0c;从而创建方便用户一键运行的可执行程序。以下是使用 Hyp…