redission实现分布式锁

article/2025/10/13 5:49:52

在开始提到Redis分布式锁之前,先说一下redis中的两个命令。

SETNX key value

setnx 是SET if Not eXists(如果不存在,则 SET)的简写。
在这里插入图片描述
用法如图,如果不存在set成功返回int的1,这个key存在了返回0。

SETEX key seconds value

上面这个命令的含义是:

将值 value关 联到 key,并将 key的生存时间设为 seconds (以秒为单位)。

如果key已经存在,setex命令将覆写旧值。

其中setex是一个原子性(atomic)操作,关联值和设置生存时间两个动作会在同一时间内完成。

这两个命令是实现redis分布式锁的关键,同时reddission底层也是通过这两个命令结合lua脚本完成redis分布式锁的

回到主题:

实现Redis的分布式锁,除了自己基于redis client原生api来实现之外,还可以使用开源框架:Redission

Redisson是一个企业级的开源Redis Client,也提供了分布式锁的支持,如果自己写代码来通过redis设置一个值,是通过下面这个命令设置的。

SET anyLock unique_value NX PX 30000

具体含义见下图:
在这里插入图片描述

这里设置的超时时间是30s,假如我超过30s都还没有完成业务逻辑的情况下,key会过期,其他线程有可能会获取到锁。

这样一来的话,第一个线程还没执行完业务逻辑,第二个线程进来了也会出现线程安全问题。所以我们还需要额外的去维护这个过期时间,太麻烦了~

而使用redission,只需要通过他的api中的lock和unlock即可完成分布式锁,他帮我们考虑了很多细节:

  • redisson所有指令都通过lua脚本执行,redis支持lua脚本原子性执行
  • redisson设置一个key的默认过期时间为30s,如果某个客户端持有一个锁超过了30s怎么办?
    redisson中有一个watchdog看门狗的概念,翻译过来就是看门狗,它会在你获取锁之后,每隔10秒帮你把key的超时时间设为30s

这样的话,就算一直持有锁也不会出现key过期了,其他线程获取到锁的问题了。

  • redisson的"看门狗"逻辑保证了没有死锁发生。
    注意:如果机器宕机了,看门狗也就没了。此时就不会延长key的过期时间,到了30s之后就会自动过期了,其他线程可以获取到锁)

在这里插入图片描述
比起自己手写代码会帮助开发者少关注贼多细节

同时redission支持多种连接模式

//单机
RedissonClient redisson = Redisson.create();
Config config = new Config();
config.useSingleServer().setAddress("myredisserver:6379");
RedissonClient redisson = Redisson.create(config);//主从
Config config = new Config();
config.useMasterSlaveServers().setMasterAddress("127.0.0.1:6379").addSlaveAddress("127.0.0.1:6389", "127.0.0.1:6332", "127.0.0.1:6419").addSlaveAddress("127.0.0.1:6399");
RedissonClient redisson = Redisson.create(config);//哨兵
Config config = new Config();
config.useSentinelServers().setMasterName("mymaster").addSentinelAddress("127.0.0.1:26389", "127.0.0.1:26379").addSentinelAddress("127.0.0.1:26319");
RedissonClient redisson = Redisson.create(config);//集群
Config config = new Config();
config.useClusterServers().setScanInterval(2000) // cluster state scan interval in milliseconds.addNodeAddress("127.0.0.1:7000", "127.0.0.1:7001").addNodeAddress("127.0.0.1:7002");
RedissonClient redisson = Redisson.create(config);

下面直接贴代码,这里使用的是单机模式,切换自己改一下连接模式就行:
1.导入依赖:

<!-- org.redisson/redisson 分布式专用--><dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.16.0</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><version>2.5.3</version></dependency>

2.编写配置类:

@SpringBootApplication
public class RedisLockApplication {public static void main(String[] args) {SpringApplication.run(RedisLockApplication.class, args);}@Beanpublic Redisson redisson(){// 单机模式Config config = new Config();config.useSingleServer().setAddress("redis://127.0.0.1:6379").setDatabase(0);return (Redisson) Redisson.create(config);}
}

3.上锁

@RestController
public class IndexController {@Resourceprivate Redisson redisson;@Resourceprivate StringRedisTemplate stringRedisTemplate; // 居然根据名字来找的,不是根据类型。。。/*** 代码有什么问题?*      1.线程安全问题,多个线程同时访问就可能出现错误,用synchronized可以解决但是性能不好*          synchronized在高并发情况下还是有bug出现,会出现超卖,可以用jmeter压测*      2.设置redis锁解决分布式场景之后,超时时间设置10s合理吗?适合场景问题?如果10s中之内没有处理完,处理到一半呢?*          15s--10s后释放锁--还需要5s,5s后释放了其他人的锁*          8s--5s后我的锁被人释放了,其他线程又来了*          循环下去,锁的是别人....这不就完全乱套了,这锁完全没用啊*        解决方法:你不是可能存在释放别人的锁的情况吗?那就设置识别号,识别到只能是自己的才能被释放*        这只是解决了释放别人的锁的问题,你自己没有执行完就已经超时的问题呢?*        答案:开启子线程定时器来延长超时时间咯,子线程每隔一段时间就去查看是否完成,没完成就加时,那这个一段时间要多长呢?*             三分之一过期时间,其他人的实践经验。*        所以:我们现在又要造轮子了吗?是否有其他人已经考虑过这个问题并做开源了呢?*        那肯定有啊,不然我写这个干吗。redisson,比jedis强大,专对分布式**      3.redisson*          大概阐述一下这个锁的操作:*          当一个redisson线程过来获取到锁时,后台会有其他线程去检查是否还持有锁,*          还持有说明还没执行结束,就会继续延长锁的时间,大概10s去轮询。(三分之一)*          另外一个线程过来,如果没有获取锁成功,就会while自旋尝试加锁。*          clientId他在底层实现了。**          3.1如果使用的是Redis主从架构呢,主节点宕了,从节点怎么处理?但这是锁还没有被同步过去,其他线程就过来访问了呢?*          3.2另外如何提升性能呢?*              - 商品库存分段存储,key不一样,每个段的数量越小性能不就越高嘛,而且锁定不同的key值** @return*/@RequestMapping("/deduct_stock")public String deductStock() {// 0.标识号String clientID = UUID.randomUUID().toString();// 1.这个相当于一把锁,控制只能一个人来String lockKey = "product001";RLock lock = redisson.getLock(lockKey); // 3.1try{
/*// 2.获取锁Boolean result = stringRedisTemplate.opsForValue().setIfAbsent(lockKey, "yjiewei");// jedis.setnx(key, value);// 3.如果突发宕机,锁没有释放掉怎么办,key过期处理(10s),但是如果在获取锁之后就出问题呢,这一步也没有成功,大招:二合一stringRedisTemplate.expire(lockKey, 10, TimeUnit.SECONDS);
*/// 2-3
/*          Boolean result = stringRedisTemplate.opsForValue().setIfAbsent(lockKey, clientID, 10, TimeUnit.SECONDS);if (!result){return "error";}
*/// 3.1 解决过期时间内还未完成操作的问题lock.lock(30, TimeUnit.SECONDS); // 先拿锁,再设置超时时间// 4.真正操作商品库存synchronized (this){int stock = Integer.parseInt(stringRedisTemplate.opsForValue().get("stock")); // jedis.get("stock");if (stock > 0){int realStock = stock - 1;stringRedisTemplate.opsForValue().set("stock", realStock + ""); // jedis.set(key, value);System.out.println("扣减成功,剩余库存:" + realStock);}else {System.out.println("扣减失败,库存不足!");}}}finally {lock.unlock(); // 释放锁
/*if (clientID.equals(stringRedisTemplate.opsForValue().get(lockKey))) {// 5.释放锁,放在finally块中防止没有释放锁导致死锁问题stringRedisTemplate.delete(lockKey);}
*/}return "end";}
}

在这里插入图片描述


http://chatgpt.dhexx.cn/article/kqsAArHo.shtml

相关文章

Java分布式锁

文章目录 1.什么是锁&#xff1f;2.什么是分布式&#xff1f;分布式场景 3.什么是分布式锁&#xff1f;4.我们应该怎么设计分布式锁&#xff1f;5.基于数据库的分布锁5.1 基于表主键唯一做分布式锁5.2 基于表字段版本号做分布式锁 6.基于 Redis 做分布式锁6.1 基于 REDIS 的 SE…

Redis分布式锁

概述 日常开发中&#xff0c;秒杀下单、抢红包等等业务场景&#xff0c;都需要用到分布式锁。而Redis非常适合作为分布式锁使用。本文将分七个方案展开&#xff0c;跟大家探讨Redis分布式锁的正确使用方式。如果有不正确的地方&#xff0c;欢迎大家指出哈&#xff0c;一起学习一…

Zookeeper分布式锁

实现一把分布式锁通常有很多方法&#xff0c;比较常见的有 Redis 和 Zookeeper。 Redis分布式锁可参考之前的文章&#xff1a; Redisson 分布式锁原理分析&#xff1a;https://blog.csdn.net/qq_42402854/article/details/123342331 Zookeeper能实现分布式锁&#xff0c;是因…

分布式锁

分布式锁实践 在不同进程需要互斥地访问共享资源时&#xff0c;分布式锁是一种非常有用的技术手段。有很多三方库和文章描述如何用Redis实现一个分布式锁管理器&#xff0c;但是这些库实现的方式差别很大&#xff0c;而且很多简单的实现其实只需采用稍微增加一点复杂的设计就可…

分布式系列之分布式锁几种实现机制

在分布式系统中&#xff0c;分布式锁用来解决分布式系统中多线程、多进程在不同机器上共享资源访问的问题。本文简要介绍分布式锁的四种实现机制&#xff0c;包括数据库、Redis缓存、Zookeeper和Etcd&#xff0c;以加深了解。 1、分布式锁介绍 在单体应用中&#xff0c;通过锁…

三种分布式锁

----------本文为学习记录如有错误帮忙指正 一、什么是分布式锁&#xff1f; 在单机系统下&#xff0c;如果多个线程同时访问一个变量或者代码片段就会产生多线程问题。&#xff08;被访问的变量或者代码片段被称之为临界区域&#xff09;这时我们就需要让所有线程按顺序一个一…

Redis实现分布式锁

目录 一、前言 为什么需要分布式锁&#xff1f; 二、基于redis实现分布式锁 为什么redis可以实现分布式锁&#xff1f; 如何实现&#xff1f; 锁的获取 锁的释放 三、如何避免死锁&#xff1f;锁的过期时间如何设置&#xff1f; 避免死锁 锁过期处理 释放其他服务的锁…

什么是分布式锁?几种分布式锁分别是怎么实现的?

一、什么是分布式锁&#xff1a; 1、什么是分布式锁&#xff1a; 分布式锁&#xff0c;即分布式系统中的锁。在单体应用中我们通过锁解决的是控制共享资源访问的问题&#xff0c;而分布式锁&#xff0c;就是解决了分布式系统中控制共享资源访问的问题。与单体应用不同的是&am…

软件需求最佳实践笔记(一)

1.软件需求最佳实践笔记 | 需求框架 前言&#xff1a;SERU是一套系统全面的需求方法论&#xff0c;可指导我们日常的软件需求工作。曾参加过徐峰老师软件需求最佳实践课程的培训&#xff0c;收益颇多&#xff0c;现通过笔记形式整理出来&#xff0c;以期与具有同样需求的读者共…

声音信号基音提取算法基频和谐波处理分析

1、内容简介 略 293-可以交流、咨询、答疑 2、内容说明 略 一、 实验原理&#xff1a; 傅里叶变换建立了信号频谱的概念。所谓傅里叶分析即分析信号的频谱(频率构成)、频带宽度等。要想合成出一段音乐,就要了解该段音乐的基波频率、谐波构成等。因此,必须采用傅里叶变换这…

软件工程—需求分析阶段

第一步、需求获取 为了保证能全面地获取信息&#xff0c;以更好地服务于产品设计和迭代&#xff0c;产品经理必须利用内部外部等多种渠道来获取用户需求。并且因渠道差异&#xff0c;产品经理所采取的方式与方法也相应会有所差异&#xff0c;所以产品经理还必须根据不同的渠道…

作业1.1利用Audacity软件分析音频

文章目录 前言实验内容实验步骤实验结果结果分析总结 前言 Audacity软件分析其余格式的音频时需要安装FFmpeg库&#xff0c;所以我们下载一个格式转换软件将音频转为MP3格式进行处理。语音信号具有短时平稳性&#xff0c;即在一个短时间范围内&#xff08;10-30ms&#xff09;…

C++ OBS源码分析与屏幕录制软件开发视频教程

本课程主要讲解OBS源码的编译&#xff0c;OBS功能实现&#xff0c;初始化&#xff0c;显示器录制&#xff0c;窗口的实现录制&#xff0c;以及录制模块源码详细分析&#xff0c;最后基于OBS源码开发了一个录制软件&#xff0c;界面如下&#xff1a; 主要有如下功能 &#xff0…

酒店管理系统-需求分析报告

目录 1.引言 1.1编制的目的 1.2术语定义 1.3参考资料 1.4相关文档 2.概述 2.1项目的描述 2.2项目的功能 2.3用户特点 3.具体需求 3.1业务需求 3.1.1主要业务 3.1.2未来增长预测 3.2用户需求 3.3应用需求 3.3.1系统功能 3.3.2主要应用及使用方式 3.4网络基本结构…

基于matlab的声波分析研究,基于MATLAB的声音信号分析与处理(共13页)

设计了一套信号采集与处理系统&#xff0c;建立了傅立叶变换算法模型&#xff0c;可获得其频谱图进行频谱分析&#xff0c;建立滤波器的设计算法模型设计了一个声音滤波器&#xff0c;建立滤波算法模型可对声音信号进行滤波。本套系统的算法建立都是基于MATLAB软件&#xff0c;…

分析评估和定位声音质量

/** * author wangdaopo * email 3168270295qq.com */ 影响音频质量和稳定性的因素 音质好坏的评价&#xff0c;响度、音高、音色&#xff0c; 测试&#xff0c;你的语音引擎是基本可用的&#xff0c;客观评测软件是RMAA&#xff08;RightMark Audio Analyzer&#xff1b;比…

声学计算机软件,常用声学仿真软件汇总

声学仿真软件根据计算原理不同大致分为以下几类&#xff1a; 一、电力声类比法 将振动系统和声学系统转化为等效电路&#xff0c;是一种0维的参数化建模方法&#xff1b; 优点&#xff1a;计算速度快&#xff1b; 缺点&#xff1a;无法预测高频响应以及复杂声波叠加&#xff1b…

荔枝软件如何测试声音,荔枝如何测自己的声音 荔枝测自己的声音方法

您可能感兴趣的话题&#xff1a; 荔枝 测自己的声音 核心提示&#xff1a;  荔枝APP有一个特色功能——声鉴卡&#xff0c;声鉴卡可以用来测试用户的音色&#xff0c;比如女神音、御姐音、少年音等等&#xff0c;很多人都想用声鉴卡测试一下自己的音色&#xff0c;却不知道荔枝…

电脑版频谱测试软件,电脑实时声音频谱PC Sound Spectrum

PC Sound Spectrum是完全免费提供给广大用户们使用的一个电脑声音实时频谱显示软件&#xff0c;可以将电脑声卡里所有的声音捕捉并转换为24段动态频谱显示&#xff0c;也可透明显示&#xff0c;拥有鼠标穿透效果&#xff0c;而且不用安装&#xff0c;没有插件&#xff0c;体积小…

软件产品案例分析

软件产品案例分析 第一部分&#xff1a; 评测&#xff1a; 上手体验&#xff1a; 说实话&#xff0c;在老师布置这个作业之前我确实不知道有K米这个APP&#xff0c;我想这是很少去KTV的原因吧。。。不过在接到这个作业后&#xff0c;我就去百度了普及了一下这个app的相关知识。…