分布式锁之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.rhkb.cn/news/326244.html

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

相关文章

立聪堂助听器29周年暨第九届助听使者活动圆满落幕

5月10日对于立聪堂来说是个特别的日子&#xff0c;这家专注于听力健康领域的公司迎来了29周年。同时&#xff0c;立聪堂第九届助听使者代表及其家人也受邀参观立聪堂南京总部&#xff0c;共庆29周年。 易被忽视的老人听力健康 大数据显示&#xff0c;我国65岁以上老人&#x…

第六节笔记及作业----Lagent AgentLego 智能体应用搭建

关于 Agent 的相关理论 大语言模型存在一些局限性&#xff0c;比如会出现幻觉问题、有时效性问题以及可靠性问题。智能体的定义是具备感知、决策和行动能力的实体。智能体主要由感知部分、大脑部分和动作部分组成。智能体有多种类型&#xff0c;如 ReAct 类型&#xff08;侧重…

如何使用 ArcGIS Pro 计算容积率

容积率是指地上建筑物的总面积与用地面积的比率&#xff0c;数值越小越舒适&#xff0c;这里为大家介绍一下如何使用ArcGIS Pro 计算容积率&#xff0c;希望能对你有所帮助。 数据来源 教程所使用的数据是从水经微图中下载的建筑和小区数据&#xff0c;除了建筑和小区数据&am…

【联通官网及APP注册/登录安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞 …

使用Flink SQL实时入湖Hudi/Hive

文章目录 1 Hudi 简介2 COW和MOR3 接入COW模式Hudi表4 使用Flink SQL查看新接表5 使用Hive查看新接表6 总结 1 Hudi 简介 Hudi是一个流式数据湖平台&#xff0c;使用Hudi可以直接打通数据库与数据仓库&#xff0c;连通大数据平台&#xff0c;支持对数据增删改查。Hudi还支持同…

软件设计中的数字:7

“ 使软件更易理解的秘密&#xff1a;米勒法则” 小游戏 学习之前先一起玩一个小游戏。 3秒钟时间&#xff0c;看看下面的图片中有多少个小块&#xff1f; 3秒到了&#xff0c;数出来了吗&#xff1f;22个。 没数出来也没关系&#xff0c;我也没数出来o(╥﹏╥)o 现在&…

[AIGC] 压缩列表了解吗?快速列表 quicklist 了解吗?

文章目录 压缩列表了解吗&#xff1f;快速列表 quicklist 了解吗&#xff1f; 压缩列表了解吗&#xff1f; 压缩列表是 Redis 为了节约内存 而使用的一种数据结构&#xff0c;是由一系列特殊编码的连续内存快组成的顺序型数据结构。 一个压缩列表可以包含任意多个节点&#xf…

3D分子生成的定制扩散框架 MolDiff - 评测

MolDiff模型是一种考虑分子键生成的3D分子生成的新模型。MolDiff是清华大学智能产业研究院马剑竹课题组发表在PMLR 2023的工作&#xff0c;第一作者是Xingang Peng&#xff0c;文章题目为&#xff1a;《 Addressing the Atom-Bond Inconsistency Problem in 3D Molecule Genera…

Mac安装jadx

1、使用命令brew安装 : brew install jadx 输入完命令,等待安装完毕 备注&#xff08;关于Homebrew &#xff09;&#xff1a; Homebrew 是 MacOS 下的包管理工具&#xff0c;类似 apt-get/apt 之于 Linux&#xff0c;yum 之于 CentOS。如果一款软件发布时支持了 homebrew 安…

STM32 PWM 计数器模式和对齐

STM32 PWM 计数器模式和对齐 1. TIM高级定时器简介2. TIM计数模式2.1 向上计数2.2 向下计数2.3 中心对齐模式&#xff08;向上/向下计数&#xff09;2.4 重复计数 3. PWM输出模式3.1 举例看下PWM中心对齐模式&#xff0c;设置参数如下&#xff1a; 4. FOC中PWM相关设置说明4.1 …

Docker学习(带图详细)

一、安装docker 参考官方文档&#xff1a;https://docs.docker.com/engine/install/centos/ 查看系统版本 [rootlocalhost ~]# cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core) [rootlocalhost ~]# [rootlocalhost ~]# uname -a Linux localhost.localdomai…

华为OD机试 - 密码输入检测(Java 2024 C卷 100分)

华为OD机试 2024C卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷C卷&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;每一题都有详细的答题思路、详细的代码注释、样例测试…

后端项目开发笔记

Maven打包与JDK版本不对应解决方法 我这里使用jdk8。 <build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configurat…

【适用全主题】WordPress原创插件:弹窗通知插件 支持内容自定义

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 适用于所有WordPress主题的弹窗插件 一款WordPress原创插件&#xff1a;弹窗通知插件 支持内容自定义 二、效果展示 1.部分代码 代码如下&#xff08;示例&#xff09;&#xff1…

BGP学习二:BGP通告原则,BGP反射器,BGP路径属性细致讲解,新手小白无负担

目录 一.AS号 二.BGP路由生成 1.network 2.import-route引入 三.BGP通告原则 1.只发布最优且有效的路由 2.从EBGP获取的路由&#xff0c;会发布给所有对等体 3.水平分割原则 4.IBGP学习BGP默认不发送给EBGP&#xff0c;但如果也从IGP学习到了这条路由&#xff0c;就发…

4. 分布式链路追踪客户端工具包Starter设计

前言 本文将从零搭建分布式链路追踪客户端工具包的Starter&#xff0c;并将在后续文章中逐步丰富支持的场景。这里首先将搭建一个最基础的Starter&#xff0c;能提供的功能和1. 看完这篇文章我奶奶都懂Opentracing了一文中的示例demo类似。 相关版本依赖如下。 opentracing-…

生成ssl证书并配置到nginx

生成ssl证书并配置到nginx 安装证书生成工具 apt-get update apt install software-properties-common add-apt-repository ppa:certbot/certbot apt-get update apt-get install certbot python3-certbot-nginx生成证书 首先在新网上创建一个A链接&#xff0c;域名与服务器做…

vue3 自定义国际化、elementPlus 国际化

自定义国际化 1. 引入 vue-i18n 插件 pnpm install vue-i18nnext 2. 页面添加语言文件目录&#xff0c;添加自定义的语言文件 3.语言目录里添加 index.ts&#xff0c; 内容如下 import { createI18n } from "vue-i18n";// 自定义语言文件 import zhCN from "…

WordPress中插入视频的两种方法详解

最近我在建设WordPress网站的时候需要上传视频&#xff0c;我使用的是Hostease的主机安装的WordPress&#xff0c;随后在咨询了他们的技术支持后获得了一些解决方法。下面将介绍WordPress中插入视频的两种方法&#xff1a;本地上传和外部引用。 本地上传视频 使用WordPress的古…

【eclipse】如何在IDE里创建一个Java Web项目?

如何在eclipse中创建一个动态Web项目并成功运行&#xff1f; 一、 最终效果 懒得写那么多了…我也不知道该怎么写了&#xff0c;有点乱&#xff0c;有问题可以在评论里留言&#xff0c;我看到会解决的&#xff0c;在这个过程中也踩到了一些坑&#xff0c;但好在有CSDN帮助解决…