【Redis(8)】Spring Boot整合Redis和Guava,解决缓存穿透、缓存击穿、缓存雪崩等缓存问题

在缓存技术的挑战及设计方案我们介绍了使用缓存技术可能会遇到的一些问题,那么如何解决这些问题呢?

在构建缓存系统时,Spring Boot和Redis的结合提供了强大的支持,而Guava的LoadingCache则为缓存管理带来了便捷的解决方案。下面我将介绍如何通过整合Spring Boot、Redis和Guava来实现一个解决缓存穿透、缓存击穿、缓存雪崩、缓存污染和缓存数据一致性问题的缓存方案。

一、整合Spring Boot与Redis

首先,我们需要在Spring Boot项目中整合原生Redis客户端。这可以通过添加Spring Boot Redis依赖来实现。

二、引入Guava

Guava的LoadingCache是一个高级缓存工具,它支持自动加载、缓存数据的自动刷新和监听器通知。

三、工具类

下面是一个三高缓存工具类的实现,它整合了Spring Boot、Redis和Guava的LoadingCache。这个工具类旨在解决缓存穿透、缓存击穿、缓存雪崩、缓存污染和缓存数据一致性问题。

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;public class CacheUtil<DataLoader extends CacheUtil.DataLoaderInterface> {private final StringRedisTemplate stringRedisTemplate;private final ValueOperations<String, String> valueOperations;private final LoadingCache<String, String> loadingCache;private final DataLoader dataLoader;@Autowiredpublic CacheUtil(StringRedisTemplate stringRedisTemplate, DataLoader dataLoader) {this.stringRedisTemplate = stringRedisTemplate;this.valueOperations = stringRedisTemplate.opsForValue();this.dataLoader = dataLoader;// 初始化Guava LoadingCache// 设置最大容量,避免缓存污染// 设置写入后过期时间,避免缓存雪崩// 使用锁机制,避免缓存击穿this.loadingCache = CacheBuilder.newBuilder().maximumSize(10000).expireAfterWrite(10, TimeUnit.MINUTES).build(new CacheLoader<String, String>() {@Overridepublic String load(String key) throws Exception {// 当缓存未命中时,调用数据加载器的方法从数据库加载数据return dataLoader.loadDataFromDatabase(key);}});}public String get(String key) {try {// 通过Guava LoadingCache获取数据// 自动处理缓存穿透和击穿return loadingCache.get(key);} catch (ExecutionException e) {// 异常处理,返回nullreturn null;}}public void set(String key, String value) {// 同时更新Redis和Guava LoadingCache// 保持数据一致性valueOperations.set(key, value);loadingCache.put(key, value);}public void update(String key, String value) {// 更新缓存数据,解决数据一致性问题set(key, value);}public void insert(String key, String value) {// 插入前检查缓存,避免缓存污染if (get(key) == null) {set(key, value);}}public void delete(String key) {// 删除Redis和Guava LoadingCache中的数据// 保持数据一致性valueOperations.delete(key);loadingCache.invalidate(key); // 使缓存项失效}// 用于在数据库更新后刷新缓存public void refreshCache(String key) {loadingCache.invalidate(key);}// 数据加载器接口,调用者需要实现该接口以提供数据加载逻辑public interface DataLoaderInterface {String loadDataFromDatabase(String key);}
}

四、使用示例

  • 实现数据加载器接口:创建一个类实现CacheUtil.DataLoaderInterface接口,提供具体的数据加载逻辑。
public class UserCacheDataLoader implements CacheUtil.DataLoaderInterface {private final UserService userService; // 假设这是您的UserService@Autowiredpublic UserCacheDataLoader(UserService userService) {this.userService = userService;}@Overridepublic String loadDataFromDatabase(String key) {// 根据键(例如用户ID)从数据库加载数据User user = userService.findById(key);if (user != null) {return user.toString(); // 将用户信息转换为字符串}return null; // 用户不存在}
}
  • 配置Spring Bean:在Spring配置中注册CacheUtil Bean。
@Configuration
public class CacheConfig {@Beanpublic CacheUtil<UserCacheDataLoader> userCacheUtil(UserCacheDataLoader userCacheDataLoader) {// 假设已经配置好StringRedisTemplate stringRedisTemplate = stringRedisTemplate(); return new CacheUtil<>(stringRedisTemplate, userCacheDataLoader);}// 其他配置...
}
  • 在应用中使用:在需要缓存的地方注入CacheUtil并使用它。
@RestController
@RequestMapping("/users")
public class UserController {private final CacheUtil<UserCacheDataLoader> userCacheUtil;@Autowiredpublic UserController(CacheUtil<UserCacheDataLoader> userCacheUtil) {this.userCacheUtil = userCacheUtil;}@GetMapping("/{userId}")public String getUserDetails(@PathVariable String userId) {// 使用CacheUtil的get方法来获取缓存数据return userCacheUtil.get(userId);}// 更新缓存数据userCacheUtil.update(key, value);// 插入缓存数据userCacheUtil.insert(key, value);// 删除缓存数据userCacheUtil.delete(key);// 数据库更新后刷新缓存userCacheUtil.refreshCache(key);
}

 

注意:

  • 请确保StringRedisTemplate和数据加载器(如UserCacheDataLoader)已经正确配置并注入到CacheUtil中。
  • 根据业务逻辑的复杂性,loadDataFromDatabase方法可能需要合理的超时和重试策略。
  • 在实际部署前,进行充分的测试,确保缓存加载逻辑在各种情况下都能正常工作。

 

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

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

相关文章

【嵌入式】keil5安装(同时兼容C51和STM32)

最近在开发STM32的时候&#xff0c;安装Keil5&#xff0c;遇到STM32和C51的共存的问题&#xff0c;在网上找了很多方法&#xff0c;又遇到一些bug&#xff0c;最终还是弄好了。因此将处理的过程记录下来&#xff0c;希望对遇到相同问题的朋友一些启发。 1、下载安装包 Keil P…

基于FPGA的频率计与串口通信(二)

接上篇&#xff0c;本文章展示基于FPGA的频率计与串口通信项目部分核心代码。 顶层文件 top.bdf //#pragma file_not_in_maxplusii_format (header "graphic" (version "1.3")) (pin(input)(rect 80 328 248 344)(text "INPUT" (rect 133 0 1…

Spark---RDD的创建分类和基础操作算子详解

一、RDD的创建 原生api提供了两种创建方式&#xff0c;一种就是读取文件textFile&#xff0c;还有一种就是加载一个scala集合parallelize。当然&#xff0c;也可以通过transformation算子来创建的RDD。 //创建RDD//加载数据&#xff0c;textFile&#xff08;参数1&#xff0c;…

新牛市新方向:探索加密货币生态的未来

序章&#xff1a;牛市来袭&#xff0c;新的探索 新的牛市来临&#xff0c;带来了加密货币世界的一次次惊喜。比特币、以太坊、Solana等生态系统在这场盛宴中展现出各自的独特魅力&#xff0c;带来了一场场引人入胜的探索之旅。让我们跟随着这些生态系统的脚步&#xff0c;一起…

基础算法前缀和与差分

前言 本次博客会介绍一维和二维的前缀和&#xff0c;以及一维二维差分的基本使用&#xff0c;尽量画图&#xff0c;多使用配合文字 使大家理解&#xff0c;希望有所帮助吧 一维前缀和 问题描述 这里有一个长度为n的数组&#xff0c;我们要算出【2,5】区间的元素和 暴力思…

Mogdb 5.0新特性:SQL PATCH绑定执行计划

前言 熟悉Oracle的dba都知道&#xff0c;生产系统出现性能问题时&#xff0c;往往是SQL走错了执行计划&#xff0c;紧急情况下&#xff0c;无法及时修改应用代码&#xff0c;dba可以采用多种方式针对于某类SQL进行执行计划绑定&#xff0c;比如SQL Profile、SPM、SQL Plan Base…

Linux——网络管理nmcli

nmcli 不能独立使用&#xff0c;需要对应的服务启动 1. NetworkManager.service 2. 网络配置和服务不相关 3. 通过 nmcl &#xff49; 建立网络配置和网卡之前的映射关系 网卡 简称&#xff1a;nmcli d DEVICE &#xff1a;物理设备 TYPE: 物理设备类型 ethernet 以太网…

C++设计模式:适配器模式(十四)

1、定义与动机 定义&#xff1a;将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的哪些类可以一起工作。 动机&#xff1a; 在软件系统中&#xff0c;由于应用环境的变化&#xff0c;常常需要将“一些现存的对象”放在新的环境…

强固型工业电脑在码头智能闸口、OCR(箱号识别)、集装箱卡车车载电脑行业应用

集装箱卡车车载电脑应用 背景介绍 针对码头集装箱卡车的调度运用, 结合码头TOS系统设计出了各种平台的车载电脑(VT系列)和车载LED显示屏(VLD系列)&#xff0c;同时提供各种安装支架&#xff0c;把车载电脑固定到狭小的驾驶室中&#xff1b;同时提供了各种天线选择&#xff08;…

【JVM常见问题总结】

文章目录 jvm介绍jvm内存模型jvm内存分配参数jvm堆中存储对象&#xff1a;对象在堆中创建分配内存过程 jvm 堆垃圾收集器垃圾回收算法标记阶段引用计数算法可达性分析算法 清除阶段标记清除算法复制算法标记压缩算法 实际jvm参数实战jvm调优jvm常用命令常用工具 jvm介绍 Java虚…

高速公路交通运输大数据平台解决方案

前言 交通运输行业面临着多重挑战。其管控困难&#xff0c;涉及广泛地理范围&#xff0c;导致监控成本高且难以及时响应&#xff1b;同时&#xff0c;行业内数据量大&#xff0c;地理信息数据繁多&#xff0c;缺乏高效的可视化工具来揭示数据规律并优化业务&#xff1b;货运和…

数据结构——第7章 查找

1 线性表的查找 数据元素和顺序表的定义 typedef struct{KeyType key;InfoType otherinfo; }ElemType; typedef struct{ElemType *R;int length; }SSTable; 1.1 顺序查找 int Search_Seq(SSTable ST,KeyType key){ST.R[0].keykey;for(int iST.length;ST.R[i].key!key;i--);…

回溯算法-组合问题

回溯算法-组合问题 77. 组合 问题描述 给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 示例 1&#xff1a; 输入&#xff1a;n 4, k 2 输出&#xff1a; [[2,4],[3,4],[2,3],[1,2],[1,3],[1,4], ]示例 2&a…

05集合-CollectionListSet

Collection体系的特点、使用场景总结 如果希望元素可以重复&#xff0c;又有索引&#xff0c;索引查询要快? 用ArrayList集合, 基于数组的。(用的最多) 如果希望元素可以重复&#xff0c;又有索引&#xff0c;增删首尾操作快? 用LinkedList集合, 基于链表的。 如果希望增…

基于SpringBoot + Vue实现的奖学金管理系统设计与实现+毕业论文+答辩PPT

介绍 角色:管理员、学院负责人、学校负责人、学生 管理员:管理员登录进入高校奖助学金系统的实现可以查看系统首页、个人中心、学生管理、学院负责人管理、学校负责人管理、奖学金类型管理、奖学金申请管理、申请提交管理、系统管理等信息 学院负责人:学院负责人登录系统后&am…

python3--lxml pytoml.core.TomlError expected_equals报错解决

文章目录 一、问题二. 解决方法&#xff1a;三. 参考&#xff1a;四. 总结 一、问题 在ubuntu的armbian上的python3中安装lxml时报错了 安装命令是 pip3 install lxml报错简略信息如下图 File "/usr/share/python-wheels/pytoml-0.1.2-py2.py3-none-any.whl/pytoml/par…

nlp(6)--构建找规律模型任务

前言 仅记录学习过程&#xff0c;有问题欢迎讨论 包含了两个例子 第一个为5分类任务 第二个为2分类任务 Demo1比Demo2难一点&#xff0c;放上边方便以后看。 练习顺序为 Demo2—>Demo1 代码 DEMO1: """ 自定义一个模型 解决 5分类问题 问题如下&#xf…

SQL概述

1. SQL的分类 SQL语言在功能上主要分为如下3大类&#xff1a; DDL&#xff08;Data Definition Languages、数据定义语言&#xff09;&#xff0c;这些语句定义了不同的数据库、表、视图、索引等数据库对象&#xff0c;还可以用来创建、删除、修改数据库和数据表的结构。主要…

2.1K Star微软开源的高质量 iot库

功能描述 该项目是一个开源的 .NET Core 实现&#xff0c;旨在帮助开发者构建适用于物联网(IoT)设备和场景的应用程序。它提供了与传感器、显示器和输入设备等相互作用所需的 GPIO 引脚、串口等硬件的接口。该仓库包含 System.Device.Gpio 库以及针对各种板卡&#xff08;如 Ra…

redis底层数据结构之ziplist

目录 一、概述二、ziplist结构三、Entry结构四、为什么ZipList特别省内存五、ziplist的缺点 上一篇 redis底层数据结构之SDS 下一篇 明天更新 一、概述 一种连续内存空间存储的顺序数据结构&#xff0c;每个元素可以是字符串或整数。优点:节省内存空间。适用于存储小规模的列表…