Java使用分布式锁来防止缓存穿透与雪崩

步骤如下:

1)选择合适的分布式锁实现:常见的分布式锁实现包括ZooKeeper、Redis和基于数据库等。根据具体情况选择最佳方案。

2)获取分布式锁:在需要进行操作时,首先尝试获取分布式锁。如果成功获取到,则可以执行相应操作;否则说明已经有其他客户端正在处理该请求,此时可以直接返回或者等待一段时间后再次尝试。

3)查询缓存数据:在获得了分布式锁之后,即可查询缓存中是否存在指定数据。如果存在,则直接返回结果;否则说明当前请求所对应的数据不存在于缓存中,需要进一步查询数据库并将其写入到缓存中去。

4)写入新数据到缓存:在完成所有操作之后,必须及时释放占用的资源(包括数据库连接、文件句柄等)以及释放所持有的分布式锁,并将新查询出来或生成出来的数据写入到缓存中去。

以下是一个简单示例代码演示如何使用Java实现基本的防止缓存穿透与雪崩功能:

public class CacheManager {private static final String LOCK_KEY = "cache_lock";// Redisson客户端private RedissonClient redisson;// 初始化方法,在系统启动时执行public void init() throws Exception {Config config = new Config();
        config.useSingleServer().setAddress("redis://localhost:6379");
        redisson = Redisson.create(config);System.out.println("CacheManager initialized.");}// 处理GET请求@GetMapping("/api")public String api(@RequestParam("id") int id){RLock lock = redisson.getLock(LOCK_KEY);try{if(lock.tryLock()){String cacheData=getFromCache(id); if(cacheData != null){ return cacheData;  }else{ String dbData=getFromDatabase(id);   saveToCache(id,dbData);    return dbData;}}else{throw new RuntimeException("无法获得全局互斥访问权!");}}finally{
            lock.unlock();}}// 从Redis里面取出指定键值对应字符串格式表示形态。private String getFromCache(int id){Jedis jedis=null;try{    
              jedis=getJedisPool().getResource();   从连接池中获取jedis对象  return jedis.get(String.valueOf(id)); 返回指定键值上面保存字符串类型数值。}catch(Exception ex){throw new RuntimeException(ex.getMessage(),ex);}finally{releaseJedis(jedis); 归还jedis对象给连接池 }}// 将指定ID对应记录从MySQL里面读取并转换为字符串格式表示形态。private String getFromDatabase(int id){Connection conn=null;PreparedStatement stmt=null;ResultSet rs=null;try{    
              conn=getConnectionFromPool();   从连接池中获取conn对象  
              stmt=conn.prepareStatement("SELECT * FROM my_table WHERE id=? AND status='active'");              stmt.setInt(1,id);              rs=stmt.executeQuery();while(rs.next()){StringBuilder sb=new StringBuilder();
                  sb.append(rs.getInt(1)).append(",");
                  sb.append(rs.getString(2)).append(",");
                  sb.append(rs.getDouble(3));                   将查询结果转换为字符串格式并添加到输出缓冲区里面去。return sb.();}throw new RuntimeException("未找到匹配记录!");}catch(SQLException ex){throw new RuntimeException(ex.getMessage(),ex);}finally{closeResultSet(rs); 关闭结果集对象  closeStatement(stmt); 关闭语句对象  releaseConnection(conn); 归还conn对象给连接池 }}// 将指定ID和关联内容保存起来,并且设置过期时间避免长期驻留内部导致空间浪费问题发生.private void saveToCache(int id,String data){Jedis jedis=null;try{    
                jedis=getJedisPool().getResource();   从连接池中获取jedis对象  long expireTime=jedis.ttl(String.valueOf(id));if(expireTime <=0 ){
                    expireTime=CACHE_EXPIRE_TIME_SEC; 设置默认过期时间长度.}                jedis.setex(String.valueOf(id),expireTime,data);}catch(Exception ex){throw new RuntimeException(ex.getMessage(),ex);}finally{releaseJedis(jedis); 归还jedis对象给连接池 }}}

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

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

相关文章

C++文件系统操作2 - 跨平台实现文件夹的创建和删除

1. 关键词2. fileutil.h3. fileutil.cpp4. filesystem_win.h5. filesystem_win.cpp6. filesystem_unix.cpp7. 源码地址 1. 关键词 C 文件系统操作 创建文件夹 创建多级目录文件夹 删除文件夹 删除文件夹下的所有文件和子目录 跨平台 2. fileutil.h #pragma once#include <…

Linux中为什么etc是存放配置文件

在计算机系统中&#xff0c;/etc 是一个目录的名称&#xff0c;通常位于Unix和类Unix操作系统中&#xff0c;如Linux。这个目录用于存放系统配置文件。/etc 的命名来源于早期Unix系统中的 "etcetera"&#xff08;拉丁语 "et cetera" 的缩写&#xff0c;意为…

AI绘画Stable Diffusion超强提示词插件!一键翻译,AI帮你写提示词!

大家好&#xff0c;我是向阳。 对于AI绘画来说&#xff0c;提示词写得好坏&#xff0c;十分影响最终生成图片的结果。会写提示词的话&#xff0c;生成的图片质量就会比较高&#xff0c;不会写的话&#xff0c;结果可能就不会好。 之前大家在使用Stable Diffuison&#xff08;以…

《数据结构与算法基础 by王卓老师》学习笔记——2.5线性表的链式表示与实现1

1.链式表示 2.链表举例 3.链式存储的相关术语 4.三个讨论题

【linux/shell案例实战】解决Linux和Windows的换行符CRLF和LF问题

目录 一.什么是Linux 和 Windows 的换行符 CRLF 和 LF 二.使用Linux 中命令 dos2unix 和 unix2dos 实现CRLF 和LF的转换 三.使用 windows 中的代码编辑器实现 CRLF 和 LF 的转换&#xff08;Notepad&#xff09; 一.什么是Linux 和 Windows 的换行符 CRLF 和 LF CR是Carria…

英语中‘How often’,‘How long’和‘How soon’的区分用法

Spark: 在英语中&#xff0c;“How often”&#xff0c;“How long”&#xff0c;和“How soon”都是询问时间相关事宜的常用短语&#xff0c;但它们的用法各有不同。以下是对这三个短语的详细区分和用法说明&#xff1a; 1. How often 定义&#xff1a;用于询问某事件在一定…

安装依赖时:Error: pngquant failed to build, make sure that libpng-dev is installed

错误原因&#xff1a;windows系统在安装依赖时可能报错&#xff0c;没有安装libping -dev 解决方法&#xff1a; 1、前往libping -dev官网&#xff1a;LIBPNG (sourceforge.io) 2、点击首行DOWNLOAD 3、进入网站点击Download Latest Verison下载安装&#xff0c;解压压缩包即…

2024.7.3作业

1. 梳理笔记(原创) 明天继续提问 2.程序运行后的输出结果为&#xff08;1&#xff09; #include <stdio.h> #define SQR(X) X*X void main() { int a10,k2,m1; a / SQR(km)/SQR(km); printf("%d\n",a); } 结果为1

STM32——GPIO(点亮LED)

一、GPIO是什么&#xff1f; 1、GPI/O(general porpose intput output):通用输入输出端口的简称&#xff0c;通俗地说&#xff0c;就是我们所学的51单片机的IO口&#xff0c;即P0_0等。但要注意&#xff1a;并非所有的引脚都是GPIO 输出模式下可控制端口输出高低电平&#xf…

程序员的加油站,各类技术文章,可视化技术,在线源码资源,在线实用工具,数据爬虫接口持续集成更新中

先挂网址&#xff1a;https://wheart.cn 可视化大屏模板与设计&#xff0c;在线预览 上百例可视化模板 技术文章、资源下载等各类资源导航页 echart在线实用demo 各种在线工具提升开发效率 echart在线代码模板

【电商指标详解】

前言&#xff1a; &#x1f49e;&#x1f49e;大家好&#xff0c;我是书生♡&#xff0c;本篇文章主要和大家分享一下电商行业中常见指标的详解&#xff01;存在的原因和作用&#xff01;&#xff01;&#xff01;希望对大家有所帮助。 &#x1f49e;&#x1f49e;代码是你的画…

Typora导出为Word

文章目录 一、场景二、安装1、网址2、解压并验证 三、配置四、重启Typora 一、场景 在使用Typora软件编辑文档时&#xff0c;我们可能需要将其导出为Word格式文件 当然我们可以直接在菜单里进行导出操作 文件-> 导出-> Word(.docx) 如果是第一次导出word文件&#xff0…

Python特征工程 — 1.3 对数与指数变换

目录 1 对数变换 1.1 对数变换的概念 1.2 对数变换实战 2 指数变换 2.1 指数变换的概念 2.2 指数变换实战 3 Box-Cox变换 3.1 Box-Cox变换概念 3.2 Box-Cox变换实战 1 对数变换 1.1 对数变换的概念 特征对数变换和指数变换是数据预处理中的两种常用技术&#xff0c;…

中国植物志(80卷)

中国植物志&#xff0c;全书共80卷126分册&#xff0c;3700页&#xff0c;记载了我国301科3408属31142种植物学名、形态特征、生态环境、地理分布、经济用途和物候期等。是研究中国植物的重要论著&#xff08;截图仅部分&#xff09;。

使用 bend-ingest-kafka 将数据流实时导入到 Databend

作者&#xff1a;韩山杰 Databend Cloud 研发工程师 https://github.com/hantmac Databend是一个开源、高性能、低成本易于扩展的新一代云数据仓库。bend-ingest-kafka 是一个专为 Databend 设计的实时数据导入工具&#xff0c;它允许用户从 Apache Kafka 直接将数据流导入到 D…

Konva.js 使用指南

简介 Konva.js 是一个用于创建 2D 图形的高性能 JavaScript 库&#xff0c;专注于提供丰富的 API 和灵活的图层管理。它适用于数据可视化、游戏开发和其他需要复杂图形和动画的应用场景。本文将介绍 Konva.js 的基本使用方法&#xff0c;包括初始化、绘制基本图形、处理事件和…

密码学原理精解【4】

文章目录 Z 256 下的希尔密码 Z_{256}下的希尔密码 Z256​下的希尔密码概述exampleK密钥选择 ∣ K ∣ − 1 |K|^{-1} ∣K∣−1 K ∗ K^* K∗ K − 1 K^{-1} K−1 Z 256 下的希尔密码 Z_{256}下的希尔密码 Z256​下的希尔密码 概述 m ≥ 2 为正整数&#xff0c;表示 m 维向量空…

linux系统中的各种命令的解释和帮助(含内部命令、外部命令)

目录 一、说明 二、命令详解 1、帮助命令的种类 &#xff08;1&#xff09;help用法 &#xff08;2&#xff09;--help用法 2、如何区别linux内部命令和外部命令 三、help和—help 四、man 命令 1、概述 2、语法和命令格式 &#xff08;1&#xff09;man命令的格式&…

Spring Cloud中的服务熔断与降级

Spring Cloud中的服务熔断与降级 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们将深入探讨在Spring Cloud中的服务熔断与降级策略。 一、什么是服务熔…

qt6 通过http查询天气的实现

步骤如下&#xff1a; cmakelist 当中&#xff0c;增加如下配置 引入包 访问远端api 解析返回的数据 cmakelist 当中&#xff0c;增加如下配置&#xff0c;作用是引入Network库。 引入包 3、访问远端api void Form1::on_pushButton_clicked() {//根据URL(http://t.weather.…