Redis之缓存穿透问题解决方案实践SpringBoot3+Docker

文章目录

  • 一、介绍
  • 二、方案介绍
  • 三、Redis Docker部署
  • 四、SpringBoot3 Base代码
      • 1. 依赖配置
      • 2. 基本代码
  • 五、缓存优化代码
      • 1. 校验机制
      • 2. 布隆过滤器
      • 3. 逻辑优化

一、介绍

当一种请求,总是能越过缓存,调用数据库,就是缓存穿透。
在这里插入图片描述
比如当请求一个数据库没有的数据,那么缓存也不会有,然后就一直请求,甚至高并发去请求,对数据库压力会增大。

二、方案介绍

  1. 如果key具有某种规则,那么可以对key增加校验机制,不符合直接返回。
  2. Redisson布隆过滤器
  3. 逻辑修改,当数据库没有此数据,以nullvalue,也插入redis缓存,但设置较短的过期时间。

三、Redis Docker部署

docker-compose示例如下,redis.conf从这里下载

redis:container_name: redisimage: redis:7.2volumes:- ./redis/redis.conf:/usr/local/etc/redis/redis.confports:- "6379:6379"command: [ "redis-server", "/usr/local/etc/redis/redis.conf" ]

四、SpringBoot3 Base代码

1. 依赖配置

		<!-- redis --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- redis 连接线程池 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId><version>2.11.1</version></dependency><!-- redisson --><dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.24.3</version></dependency>
spring: data:redis:host: 192.168.101.65  # Redis服务器的主机名或IP地址port: 6379  # Redis服务器的端口号password:  # 用于连接Redis服务器的密码database: 0  # 要连接的Redis数据库的索引号lettuce:pool:max-active: 20  # 连接池中最大的活跃连接数max-idle: 10  # 连接池中最大的空闲连接数min-idle: 0  # 连接池中最小的空闲连接数timeout: 10000  # 连接超时时间(毫秒)lock-watchdog-timeout: 100  # Redisson的分布式锁的看门狗超时时间(毫秒)

2. 基本代码

要演示的代码很简单,就是一个携带courseId请求过来,调用下面的service函数,然后查询数据库。

@Overridepublic CoursePublish getCoursePublish(Long courseId) {return coursePublishMapper.selectById(courseId);}

当我们使用redis改造时,基本代码如下

@Overridepublic CoursePublish getCoursePublishCache(Long courseId) {String key = "content:course:publish:" + courseId;//先查询redisObject object = redisTemplate.opsForValue().get(key);if (object != null){String string = object.toString();CoursePublish coursePublish = JSON.parseObject(string, CoursePublish.class);return coursePublish;}else {//后查询数据库CoursePublish coursePublish = getCoursePublish(courseId);if (coursePublish != null){redisTemplate.opsForValue().set(key, JSON.toJSONString(coursePublish));}return coursePublish;}}

五、缓存优化代码

1. 校验机制

我这里的id没规则,所以加不了,跳过。

2. 布隆过滤器

读取yaml配置

@Data
@Component
@ConfigurationProperties(prefix = "spring.data.redis")
public class RedisProperties {private String host;private int port;private String password;private int database;private int lockWatchdogTimeout;
}

配置RedissonClient

@Slf4j
@Configuration
public class RedissionConfig {@Autowiredprivate RedisProperties redisProperties;@Beanpublic RedissonClient redissonClient() {RedissonClient redissonClient;Config config = new Config();//starter依赖进来的redisson要以redis://开头,其他不用String url = "redis://"+ redisProperties.getHost() + ":" + redisProperties.getPort();config.useSingleServer().setAddress(url)//.setPassword(redisProperties.getPassword()).setDatabase(redisProperties.getDatabase());try {redissonClient = Redisson.create(config);return redissonClient;} catch (Exception e) {log.error("RedissonClient init redis url:[{}], Exception:", url, e);return null;}}
}

把布隆过滤器加到service,如下

	private RBloomFilter<String> bloomFilter;@PostConstructpublic void init(){//初始化布隆过滤器bloomFilter = redissonClient.getBloomFilter("bloom-filter");bloomFilter.tryInit(100, 0.003);List<CoursePublish> coursePublishList = coursePublishMapper.selectList(new LambdaQueryWrapper<CoursePublish>());coursePublishList.forEach(coursePublish -> {String key = "content:course:publish:" + coursePublish.getId();bloomFilter.add(key);});}@Overridepublic CoursePublish getCoursePublishCache(Long courseId) {String key = "content:course:publish:" + courseId;//布隆过滤器boolean contains = bloomFilter.contains(key);if (!contains){return null;}//先查询redisObject object = redisTemplate.opsForValue().get(key);if (object != null){String string = object.toString();CoursePublish coursePublish = JSON.parseObject(string, CoursePublish.class);return coursePublish;}else {//后查询数据库CoursePublish coursePublish = getCoursePublish(courseId);if (coursePublish != null){bloomFilter.add(key);redisTemplate.opsForValue().set(key, JSON.toJSONString(coursePublish));}return coursePublish;}}

3. 逻辑优化

当数据库没有此数据,以nullvalue,也插入redis缓存,但设置较短的过期时间。

            //后查询数据库CoursePublish coursePublish = getCoursePublish(courseId);if (coursePublish != null) {bloomFilter.add(key);redisTemplate.opsForValue().set(key, JSON.toJSONString(coursePublish));}else {redisTemplate.opsForValue().set(key, JSON.toJSONString(coursePublish), 10, TimeUnit.SECONDS);}return coursePublish;

在这里插入图片描述

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

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

相关文章

阿里云国际站如何助力餐饮行业出海?

近些年&#xff0c;中国企业出海方兴未艾。全球不同国家的经济政治诉求加剧了商业领域的博弈&#xff0c;全球产业供应链格局持续发生深刻变化。无论是海外建厂&#xff0c;还是海外找市场&#xff0c;中国产业链的全球布局蔚然成风,企业想突破现阶段瓶颈&#xff0c;谋求更好的…

⭐北邮复试刷题106. 从中序与后序遍历序列构造二叉树__递归分治 (力扣每日一题)

106. 从中序与后序遍历序列构造二叉树 给定两个整数数组 inorder 和 postorder &#xff0c;其中 inorder 是二叉树的中序遍历&#xff0c; postorder 是同一棵树的后序遍历&#xff0c;请你构造并返回这颗 二叉树 。 示例 1: 输入&#xff1a;inorder [9,3,15,20,7], postor…

ros自定义action记录

文章目录 自定义action1. 定义action文件2. 修改 package.xml3. 修改 CMakeLists.txt4. 运行 catkin build5. simple_action_server.py6. simple_action_client.py 测试 自定义action ros 版本&#xff1a;kinetic 自定义test包的文件结构如下 |-- test | |-- CMakeLists.t…

Internet Download Manager 6.42.3 (IDM) 中文免激活绿色版

相信很多网友都遇到过一种情况&#xff0c;网页有些视频资源或者音频资源不知道如何下载&#xff0c;一直不知道如何解决&#xff0c;为此小编特意带来了这款&#xff1a;Internet Download Manager电脑版&#xff0c;这是一款非常专业且十分好用的下载工具&#xff0c;也就是大…

Android 11以上获取不到第三方app是否安装

开年第一篇&#xff0c;处理了一下年前的小问题。 问题&#xff1a;本地app跳转到第三方app地图进行导航&#xff0c;获取不到第三方地图是否安装。 解决&#xff1a; 1.添加包名 This can be done by adding a <queries> element in the Android manifest.在app下的…

1408: [宁波25届]方格稿纸

题目描述 小猪在小学中认识了很多的字&#xff0c;终于会写一点作文了。某天小猪买了一张方格稿纸来写作文,n 行m 列,形状如下所示&#xff1a; 上图中nm5 。 某天小猪的邻居小小猪来小猪家玩&#xff0c; 用黑墨水笔把小猪新买的方格稿纸涂黑了很多格子。 每个格子不是完全黑…

psp游戏存档收集SAVEDATA

不想从头开始 ppsspp存档目录 pc&#xff1a;ppsspp解压目录\memstick\PSP\SAVEDATA 安卓&#xff1a;根目录\PSP\SAVEDATA 噬神者2(日版) NPJH50832099c645531020001000 風燐-https://wwl.lanzouq.com/iI1R01owozxa 咲夜-https://wwl.lanzouq.com/id1tX1owp2uf につてのぬ…

华为笔记本原厂系统镜像恢复安装教程方法

1.安装方法有两种&#xff0c;一种是用PE安装&#xff0c;一种是华为工厂包安装&#xff08;安装完成自带F10智能还原&#xff09; 若没有原装系统文件&#xff0c;请在这里远程恢复安装&#xff1a;https://pan.baidu.com/s/166gtt2okmMmuPUL1Fo3Gpg?pwdm64f 提取码:m64f …

Pormise---如何解决javascript中回调的信任问题?【详解】

本人编程小白一枚&#xff0c;希望多多包涵~ 如果阅读有疑问的话&#xff0c;欢迎评论或私信&#xff01;&#xff01; 本人会很热心的阐述自己的想法&#xff01;谢谢&#xff01;&#xff01;&#xff01; 文章目录 回调中的信任问题回调给我们带来的烦恼&#xff1f;调用过早…

【深度学习:对象跟踪】对象跟踪完整指南 [教程]

【深度学习&#xff1a;对象跟踪】对象跟踪完整指南 [教程] 什么是计算机视觉中的对象跟踪&#xff1f;对象跟踪有哪些不同类型&#xff1f;图像跟踪视频跟踪单目标跟踪多对象跟踪 计算机视觉中对象跟踪的用例监测零售自动驾驶汽车医疗保健 对象跟踪方法步骤 1&#xff1a;目标…

客户端web开发工具

文章目录 安全网络Linter-->捕获代码错误-->eslint源代码控制-->Git代码格式化-->Prettier打包工具--Parcel--Webpack 转换--Babel开发后阶段测试工具配置工具其他 node&#xff0c;npm、yarnnode.js包管理器npmyarn https://developer.mozilla.org/zh-CN/docs/Lea…

安卓系统和iOS系统的手机备忘录同步数据方法

在这个智能手机时代&#xff0c;安卓与iOS系统犹如两位王者&#xff0c;各自拥有庞大的用户群体。有人钟情于安卓的开放与多样&#xff0c;有人偏爱iOS的流畅与稳定。甚至&#xff0c;有些人为了满足不同需求&#xff0c;同时使用着两个系统的手机。我就是其中的一员。 工作中…

攻防世界-web-Training-WWW-Robots

题目信息 In this little training challenge, you are going to learn about the Robots_exclusion_standard. The robots.txt file is used by web crawlers to check if they are allowed to crawl and index your website or only parts of it. Sometimes these files rev…

你正在读的书,暴露了你的阶层!丰富自己吧!——早读

明天大概率可以看鸽子了 引言Python代码第一篇 人民日报 全网等的图来了&#xff01;当故宫“遇上”龙年初雪第二篇 人民日报【夜读】一个人最好的生活方式&#xff0c;是丰富自己第三篇&#xff08;跳&#xff09; 洞见 你正在读的书&#xff0c;暴露了你的阶层第四篇&#xf…

Maven私服搭建Nexus3

第一部分&#xff1a;仓库部署 下载地址&#xff1a;https://help.sonatype.com/en/download.html 备用下载链接&#xff0c;部分已经失效了 解压后会有两个文件夹&#xff1a; nexus-3.20.1-01 sonatype-work 访问地址配置路径 \nexus-3.20.1-01\bin\nexus.vmoptions -Xms1…

喀秋莎画中画怎么设置 喀秋莎画中画视频怎么导出 喀秋莎什么意思 camtasia studio下载

画中画视频&#xff0c;顾名思义&#xff0c;就是在一个视频中有两个画面&#xff0c;游戏解说、微课等类型的视频常常就以画中画的形式出现。作为一款专业的视频编辑软件&#xff0c;使用camtasia可以轻松地制作画中画视频并导出。接下来我将为大家介绍&#xff1a;喀秋莎画中…

每日coding 337打家劫舍III

337. 打家劫舍 III 小偷又发现了一个新的可行窃的地区。这个地区只有一个入口&#xff0c;我们称之为 root 。 除了 root 之外&#xff0c;每栋房子有且只有一个“父“房子与之相连。一番侦察之后&#xff0c;聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。…

【Linux】日志命令行练习(持续更新)

文章目录 前言环境情景1. 获取实时日志2. 关键字定位3. 关键字取并集4. 关键字取交集5. 关键字取差集6. 关键字实时日志捕获7. 关键词上下文打印8. 关键词滚动搜索9. 看最早的日志信息 前言 公司生产问题需要登录堡垒机排查。 没有日志平台的情况下&#xff0c;生产问题同样要…

【Linux】自主WEB服务器实现

自主web服务器实现 1️⃣构建TcpServer2️⃣构建HttpServer3️⃣构建HttpRequest和HttpResponseHttp请求报文格式Http相应报文读取、处理请求&构建响应读取请求中的一行读取请求中需要注意的点 4️⃣CGI模式判断是否需要用CGI处理请求构建任务&线程池管理 5️⃣实验结果…

《图解设计模式》笔记(二)交给子类

三、Template Method模式&#xff1a;将具体处理交给子类 示例程序类图 public static void main(String[] args) {// 生成一个持有H的CharDisplay类的实例AbstractDisplay d1 new CharDisplay(H);// 生成一个持有"Hello, world."的StringDisplay类的实例AbstractD…