分布式锁之RedissonLock

什么是Redisson?
俗话说他就是看门狗,看门狗机制是一种用于保持Redis连接活跃性的方法,通常用于分布式锁的场景。看门狗的工作原理是:当客户端获取到锁之后,会对Redis中的一个特定的键设置一个有限的过期时间,然后每隔一段时间(默认是15秒),客户端会对这个键“续约”,即重新设置它的过期时间,以此来保持锁的持有状态,防止锁因为某些原因(如客户端崩溃或网络问题)而被释放。
在这里插入图片描述
以下是核心实战部分
配置文件读取

@ConfigurationProperties(prefix = "spring.redis.redisson"
)
@Data
public class RedissonProperties {/*** key前缀*/private String keyPrefix;/*** 拿锁等待时间(毫秒)*/private long waitTime = 10000;/*** 默认ttl时间(毫秒)*/private long leaseTime = 60000;@Value("${spring.redis.redisson.config.clusterServersConfig.nodeAddresses}")private String nodeAddresses;@Value("${spring.redis.redisson.config.clusterServersConfig.scanInterval}")private Integer scanInterval;@Value("${spring.redis.redisson.config.threads}")private Integer threads;@Value("${spring.redis.redisson.config.nettyThreads}")private Integer nettyThreads;@Value("${spring.redis.redisson.config.transportMode}")private String transportMode;
}

yml文件

spring:##redis集群配置redis:database: 0timeout: 5000msredisson:config:clusterServersConfig:nodeAddresses: redis://10.xxx.xx.x1:6379,redis://10.xxx.xx.x2:6379,redis://10.xxx.xx.x3:6379scanInterval: 1000nettyThreads: 0threads: 0transportMode: NIOkey-prefix: test:keylease-time: 80000wait-time: 50000

redisson自动配置类

@Configuration
@ConditionalOnClass({Redisson.class})
@EnableConfigurationProperties({RedissonProperties.class})
@Slf4j
public class RedissonAutoConfiguration {@Bean@ConditionalOnMissingBean({RedisConnectionFactory.class})public RedissonConnectionFactory redissonConnectionFactory(RedissonClient redisson) {return new RedissonConnectionFactory(redisson);}@Bean(destroyMethod = "shutdown")@ConditionalOnMissingBean({RedissonClient.class})public RedissonClient redisson(RedissonProperties redissonProperties) throws IOException {Config config = new Config();config.useClusterServers().addNodeAddress(redissonProperties.getNodeAddresses().split(",")).setScanInterval(redissonProperties.getScanInterval());config.setThreads(redissonProperties.getThreads()).setNettyThreads(redissonProperties.getNettyThreads()).setTransportMode(TransportMode.valueOf(redissonProperties.getTransportMode()));return Redisson.create(config);}@Bean@ConditionalOnMissingBean(name = {"redisTemplate"})public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {RedisTemplate<Object, Object> template = new RedisTemplate();template.setConnectionFactory(redisConnectionFactory);return template;}@Bean@ConditionalOnMissingBeanpublic StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {StringRedisTemplate template = new StringRedisTemplate();template.setConnectionFactory(redisConnectionFactory);return template;}}

redis的缓存类实现

@Service
public class RedisCache {@Autowiredprivate RedissonClient redisson;@Autowiredprivate RedissonProperties redissonProperties;/*** 缓存** @param key 缓存key* @param <T>* @return 缓存返回值*/public <T> T get(String key) {RBucket<T> bucket = redisson.getBucket(getKey(key));return bucket.get();}/*** 以string的方式读取缓存** @param key 缓存key* @return 缓存返回值*/public String getString(String key) {RBucket<String> bucket = redisson.getBucket(getKey(key), StringCodec.INSTANCE);return bucket.get();}/*** 以string的方式保存缓存(与其他应用共用redis时需要使用该函数)** @param key     缓存key* @param value   缓存值* @param expiredTime 缓存过期时间*/public void putString(String key, String value, long expiredTime) {RBucket<String> bucket = redisson.getBucket(getKey(key), StringCodec.INSTANCE);bucket.set(value, expiredTime, TimeUnit.MILLISECONDS);}/*** 如果不存在则写入缓存(string方式,不带有redisson的格式信息)** @param key     缓存key* @param value   缓存值* @param expiredTime 缓存过期时间*/public boolean putStringIfAbsent(String key, String value, long expiredTime) {RBucket<String> bucket = redisson.getBucket(getKey(key), StringCodec.INSTANCE);return bucket.trySet(value, expiredTime, TimeUnit.MILLISECONDS);}/*** 设置缓存** @param key     缓存key* @param value   缓存值* @param expiredTime 缓存过期时间* @param <T>     类型*/public <T> void put(String key, T value, long expiredTime) {RBucket<T> bucket = redisson.getBucket(getKey(key));bucket.set(value, expiredTime, TimeUnit.MILLISECONDS);}/*** 如果不存在则设置缓存** @param key     缓存key* @param value   缓存值* @param expiredTime 缓存过期时间* @param <T>     类型*/public <T> void putIfAbsent(String key, T value, long expiredTime) {RBucket<T> bucket = redisson.getBucket(getKey(key));bucket.trySet(value, expiredTime, TimeUnit.MILLISECONDS);}/*** 移除缓存** @param key*/public void remove(String key) {redisson.getBucket(getKey(key)).delete();}/*** 判断缓存是否存在** @param key* @return*/public boolean exists(String key) {return redisson.getBucket(getKey(key)).isExists();}private String getKey(String key) {return StringUtils.format("{0}:{1}", redissonProperties.getKeyPrefix(), key);}

获取和释放分布式锁接口
DistributedLock

/*** get分布式锁* @param lockKey* @param requestId* @param expireTime* @return*/public boolean getDistributedLock(String lockKey, String requestId, long expireTime);/*** remove分布式锁* @param lockKey* @param requestId* @return*/public boolean removeDistributedLock(String lockKey, String requestId);

实现DistributedLock的实现类逻辑

@Service
public class RedisDistributedLocker implements DistributedLocker {private static final Logger logger = LoggerFactory.getLogger(RedisDistributedLocker.class);@Autowiredprivate RedissonClient redisson;@Autowiredprivate RedissonProperties redissonProperties;public boolean getDistributedLock(String lockKey, String flagId, long expireTime) {boolean success;try {if (expireTime == 0) {expireTime = redissonProperties.getLeaseTime();}lockKey = StringUtils.format("{0}:{1}", redissonProperties.getKeyPrefix(), lockKey);RLock locker = redisson.getLock(lockKey);success = locker.tryLock(redissonProperties.getWaitTime(), expireTime, TimeUnit.MILLISECONDS);} catch (Exception e) {success = false;logger.error(StringUtils.format("获取分布式锁失败,lockKey={0}, flagId={1}, expirTime={2}", lockKey, flagId, expireTime), e);}return success;}public boolean releaseDistributedLock(String lockKey, String flagId) {boolean success = false;try {lockKey = StringUtils.format("{0}:{1}", redissonProperties.getKeyPrefix(), lockKey);RLock locker = redisson.getLock(lockKey);if (locker.isHeldByCurrentThread()) {locker.unlock();success = true;}} catch (Exception e) {success = false;logger.error(StringUtils.format("分布式锁失败,lockKey={0}, flagId={1}", lockKey, flagId), e);}return success;}

在需要的业务场景下使用 以下为伪代码

try {boolean ock = distributedLocker.getDistributedLock(lockKey, flagId, 9000L);if (!ock) {return;}// 实现自己的业务逻辑。。。。。。。。。。。。。。。。。。。。。。。。。} catch (Exception e) {e.printStackTrace();throw new RuntimeException(e.getMessage());} finally {distributedLocker.releaseDistributedLock(lockKey, flagId);}

以上的是分布式锁之RedissonLock 若需完整代码 可识别二维码后 给您发代码。
在这里插入图片描述

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

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

相关文章

[附源码]传世手游_玲珑传世_GM_安卓搭建教程

本教程仅限学习使用&#xff0c;禁止商用&#xff0c;一切后果与本人无关&#xff0c;此声明具有法律效应&#xff01;&#xff01;&#xff01;&#xff01; 教程是本人亲自搭建成功的&#xff0c;绝对是完整可运行的&#xff0c;踩过的坑都给你们填上了。 如果你是小白也没…

了解进程和线程

一、进程和线程 类比&#xff1a; 一个工厂&#xff0c;至少有一个车间&#xff0c;一个车间中至少有一个工人&#xff0c;最终是工人在工作。 一个程序&#xff0c;至少有一个进程&#xff0c;一个进程中至少有一个线程&#xff0c;最终是线程在工作。 进程&#xff1a;是计…

乡村振兴与乡村旅游深度融合:依托乡村自然和文化资源,发展乡村旅游产业,促进农民增收致富,打造特色美丽乡村

目录 一、引言 二、乡村振兴与乡村旅游的内在联系 三、依托乡村自然和文化资源发展乡村旅游产业 &#xff08;一&#xff09;挖掘乡村自然资源优势&#xff0c;打造特色旅游品牌 &#xff08;二&#xff09;挖掘乡村文化资源内涵&#xff0c;丰富旅游活动内容 四、促进农…

新手做视频号电商,做什么样的产品好卖?适合不会选类目的新手看

大家好&#xff0c;我是电商花花&#xff0c;专注做电商的花花。 视频号现在的发展可以说是非常好的&#xff0c;拥有着空前的市场和流量&#xff0c;随着视频号小店新项目对电商的冲击&#xff0c;让更多创业者和新手商家开始涌入视频号电商的行列。 想要在新项目中抢占流量…

【客户案例】禅道软件助力长虹新网实现研发项目管理创新

四川长虹新网科技有限责任公司&#xff08;以下简称长虹新网&#xff09;深耕全球运营商市场二十多年&#xff0c;具备行业领先的软硬件研发、制造、全球化市场营销能力&#xff0c;持续服务国内外200多家主流电信及广电运营商、垂直行业服务商&#xff0c;与合作伙伴共同成长。…

Windows11系统安装Mysql8之后,启动服务net start mysql报错“服务没有响应控制功能”的解决办法

问题 系统环境&#xff1a;Windows11 数据库版本&#xff1a;Mysql8 双击安装&#xff0c;一路下一步&#xff0c;完成&#xff0c;很顺利&#xff0c;但是开启服务后 net start mysql 报错&#xff1a; 服务没有响应控制功能。 请键入 NET HELPMSG 2186 以获得更多的帮助 不…

echarts树图 改文本显示的地方的样式

树图改文本显示的时候的样式 虽然有点越改越丑 其中有一些失败的尝试 forammter 无法识别html元素 所以对于tooptips有用的html元素定义获取返回在这里写的话是不生效的 rich配置项里面的backgroundColor官方说支持 html元素和canvas元素 已经图片url 没有详细试验 官网地址 h…

代码签名证书的重要作用及申请途径

代码签名技术是一种确保软件完整性和来源可信度的安全措施。它通过数字证书和加密算法为软件代码或可执行文件加上一个“签名”&#xff0c;以此验证软件未被篡改&#xff0c;并确认其来源于可信赖的开发者。 一、代码签名证书的重要作用 1、提高下载率和安装率&#xff1a;用…

Linux提权--Rsync(未授权访问) Docker 组挂载

免责声明:本文仅做技术学习与交流... 目录 Rsync&#xff08;未授权访问&#xff09; 介绍: 靶场及过程: 提权过程&#xff1a; Docker 组挂载 原理: 复现&#xff1a; 利用&#xff1a; 具体操作: 1-确定是否有docker服务 2-查看用户是否在docker组里面 3-执行命…

包管理工具npm、cnpm、yarn、NVM

文章目录 npmnpm基本使用npm搜索包生产环境与开发环境开发依赖与生产依赖全局安装环境变量Path安装包依赖安装指定版本的包、删除依赖配置命令别名 cnpm安装操作命令&#xff1a;配置 yarnyarn安装及常用命令yarn 配置淘宝镜像 NVM使用常用命令 扩展内容npm和yarn的选择npm发布…

USB转串口芯片CH341、CH372、CH374、CH375等的电路及 PCB 设计的重要注意事项

前言 USB芯片的电路和PCB设计参考及注意事项&#xff0c;含CH34X、CH37X等系列芯片的电路设计说明。涉及工作稳定性和抗干扰以及USB-HOST带电热插拔。基于 USB 芯片的电路及 PCB 设计的重要注意事项 版本&#xff1a;2E 1、摘要 本文主要针对以下因电路及 PCB 设计不佳而引起…

文档解析与向量化技术加速多模态大模型训练与应用

前言 随着人工智能技术的不断发展&#xff0c;多模态大模型作为一种新型的机器学习技术&#xff0c;逐渐成为人工智能领域的热点话题。多模态大模型能够处理多种媒体数据&#xff0c;如文本、图像、音频和视频等&#xff0c;并通过学习不同模态之间的关联&#xff0c;实现更加…

Q1咖啡机行业线上市场(京东天猫淘宝)销售数据分析

回顾疫情那几年&#xff0c;咖啡机市场可能是大环境带动下爆发飞速的品类之一。在整体厨房小家电大盘销售不佳的情况下&#xff0c; 咖啡机市场的表现是亮眼的。而今年Q1季度&#xff0c;在厨卫小电市场整体低迷的状态下&#xff0c;咖啡机市场依然保持着稳中向好的趋势。 根据…

树莓派|连接CSI接口摄像头+opencv

CSI&#xff08;Camera Serial Interface&#xff09;接口摄像头是一种常见的嵌入式系统或移动设备中使用的摄像头接口。它通常用于与处理器或图像传感器进行直接连接&#xff0c;实现高速的图像数据传输。 CSI接口摄像头具有以下特点&#xff1a; 高速传输&#xff1a;CSI接口…

Spring MVC(五) 文件上传

1 单文件上传 在程序开发中&#xff0c;有时候需要上传一些文件。我们在学习Servlet的时候&#xff0c;也做过文件上传的操作&#xff0c;只不过基于Servlet的文件上传操作起来过于复杂&#xff0c;因此所有的MVC框架都提供了自己的文件上传操作&#xff0c;基本上都是基于File…

UE5 FARFilter筛选器使用方法

UE5 查找资源时可以用FARFilter进行筛选&#xff0c;之前可以用ClassNames进行筛选&#xff0c;但是5.1之后就弃用这个属性改成ClassPaths属性 构造一个FTopLevelAssetPath对象需要两个FName参数&#xff0c;但是没找到应该传什么 查找官方文档&#xff0c;明显是错误的&#x…

AAAI: Generalized Singular Value Thresholding论文阅读

1 Abstract 这篇论文研究了与非凸函数g相关的广义奇异值阈值(Generalized Singular Value Thresholding, GSVT)算子Proxσ g ()&#xff0c;定义为 P r o x g σ ( B ) arg ⁡ min ⁡ X ∑ i 1 m g ( σ i ( X ) ) 1 2 ∥ X − B ∥ F 2 , \mathbf{Prox}_{g}^{\sigma}(\mat…

实验名称:TCP 连接管理

目录 实验目的&#xff1a; 实验原理&#xff1a; 实验步骤&#xff1a; 1) 启动WireShark&#xff0c;设置抓包状态 2) 访问指定服务器 &#xff0c;通过Wireshark抓取通信数据报文 3) 分析TCP连接建立的三次握手和连接释放的四次握手过程 原始数据记录&#xff1a; 实…

【数据结构陈越版笔记】第1章 概述【习题】

1. 碎碎念 我这答案做的可能不对&#xff0c;如果不对&#xff0c;欢迎大家指出错误 2. 答案 1.1 判断正误 &#xff08;1&#xff09; N ( log N ) 2 N(\text{log}N)^{2} N(logN)2是 O ( N 2 ) O(N^{2}) O(N2)的。 &#xff08;2&#xff09; N 2 ( log N ) 2 N^{2}(\text…

HTML/CSS3

1.CSS CSS的作用在于在HTML的基础上(决定网页的内容和结构)对网页进行排版布局 对网页中的元素提供样式 使得网页显得更加精美CSS全称是cascading style sheets 即层叠样式表CSS样式的书写格式&#xff1a;样式名: 样式值 例如&#xff1a;color: red建议:之后进行空格 CSS样式…