分析redis实现分布式锁的思路

文章目录

  • 1、基于redis实现分布式锁:利用key的唯一性
    • 1.1、独占排他
    • 1.2、死锁问题
      • 1.2.1、redis客户端程序获取了锁之后,服务器立马宕机,就会导致死锁。
      • 1.2.2、不可重入:可重入
    • 1.3、原子性:加锁和过期之间:set k v nx ex 3
    • 1.4、防误删:给锁添加 uuid 唯一标识
    • 1.5、可重入锁:
  • 2、代码实现一个基本分布式锁
    • 2.1、AlbumInfoApiController --》testLock()
    • 2.2、AlbumInfoServiceImpl --》testLock()
  • 3、分布式锁程序存在的问题及测试
    • 3.1、AlbumInfoServiceImpl --》testLock()

1、基于redis实现分布式锁:利用key的唯一性

1.1、独占排他

1.2、死锁问题

1.2.1、redis客户端程序获取了锁之后,服务器立马宕机,就会导致死锁。

解决方案:给锁添加过期时间,时间到了自动释放锁。

1.2.2、不可重入:可重入

1.3、原子性:加锁和过期之间:set k v nx ex 3

判断和删除之间:lua 脚本。

1.4、防误删:给锁添加 uuid 唯一标识

先判断是否是自己的锁,如果是才能删除。

1.5、可重入锁:

锁操作:加锁、解锁、自旋
在这里插入图片描述

2、代码实现一个基本分布式锁

2.1、AlbumInfoApiController --》testLock()

@Tag(name = "专辑管理")
@RestController
@RequestMapping("api/album/albumInfo")
@SuppressWarnings({"unchecked", "rawtypes"})
public class AlbumInfoApiController {@GetMapping("test/lock")public Result testLock() {this.albumInfoService.testLock();return Result.ok("测试分布式锁案例");}}

2.2、AlbumInfoServiceImpl --》testLock()

    @Overridepublic  void testLock(){// 加锁Boolean lock = this.redisTemplate.opsForValue().setIfAbsent("lock", "111");if (!lock) {try {// 获取锁失败,进行自旋Thread.sleep(50);this.testLock();} catch (InterruptedException e) {throw new RuntimeException(e);}}// 获取锁成功,执行业务Object numObj = this.redisTemplate.opsForValue().get("num");if (numObj == null) {this.redisTemplate.opsForValue().set("num", 1);return;}Integer num = Integer.parseInt(numObj.toString());this.redisTemplate.opsForValue().set("num", ++num);// 解锁this.redisTemplate.delete("lock");}

启动多个运行实例:
在这里插入图片描述
在这里插入图片描述
redis中的值重新改为0。

[root@localhost ~]# ab -n 5000 -c 100 http://192.168.74.1:8500/api/album/albumInfo/test/lock
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking 192.168.74.1 (be patient)
Completed 500 requests
Completed 1000 requests
Completed 1500 requests
Completed 2000 requests
Completed 2500 requests
Completed 3000 requests
Completed 3500 requests
Completed 4000 requests
Completed 4500 requests
Completed 5000 requests
Finished 5000 requestsServer Software:        
Server Hostname:        192.168.74.1
Server Port:            8500Document Path:          /api/album/albumInfo/test/lock
Document Length:        76 bytesConcurrency Level:      100
Time taken for tests:   16.625 seconds
Complete requests:      5000
Failed requests:        577(Connect: 0, Receive: 0, Length: 577, Exceptions: 0)
Write errors:           0
Total transferred:      2352885 bytes
HTML transferred:       382885 bytes
Requests per second:    300.75 [#/sec] (mean)
Time per request:       332.506 [ms] (mean)
Time per request:       3.325 [ms] (mean, across all concurrent requests)
Transfer rate:          138.21 [Kbytes/sec] receivedConnection Times (ms)min  mean[+/-sd] median   max
Connect:        0    3   2.6      2      38
Processing:    11  306 566.7     92    6553
Waiting:       10  305 566.7     92    6552
Total:         11  308 567.5     95    6560Percentage of the requests served within a certain time (ms)50%     9566%    18875%    31880%    42490%    83795%   140598%   219099%   2905100%   6560 (longest request)

在这里插入图片描述

3、分布式锁程序存在的问题及测试

3.1、AlbumInfoServiceImpl --》testLock()

    @Overridepublic  void testLock(){// 加锁Boolean lock = this.redisTemplate.opsForValue().setIfAbsent("lock", "111");if (!lock) {try {// 获取锁失败,进行自旋Thread.sleep(50);this.testLock();} catch (InterruptedException e) {throw new RuntimeException(e);}}else {// 获取锁成功,执行业务Object numObj = this.redisTemplate.opsForValue().get("num");if (numObj == null) {this.redisTemplate.opsForValue().set("num", 1);return;}Integer num = Integer.parseInt(numObj.toString());this.redisTemplate.opsForValue().set("num", ++num);// 解锁this.redisTemplate.delete("lock");}}

启动多个运行实例:
在这里插入图片描述
在这里插入图片描述
redis中的值重新改为0。

[root@localhost ~]# ab -n 5000 -c 100 http://192.168.74.1:8500/api/album/albumInfo/test/lock
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking 192.168.74.1 (be patient)
Completed 500 requests
Completed 1000 requests
Completed 1500 requests
Completed 2000 requests
Completed 2500 requests
Completed 3000 requests
Completed 3500 requests
Completed 4000 requests
Completed 4500 requests
Completed 5000 requests
Finished 5000 requestsServer Software:        
Server Hostname:        192.168.74.1
Server Port:            8500Document Path:          /api/album/albumInfo/test/lock
Document Length:        76 bytesConcurrency Level:      100
Time taken for tests:   46.550 seconds
Complete requests:      5000
Failed requests:        683(Connect: 0, Receive: 0, Length: 683, Exceptions: 0)
Write errors:           0
Total transferred:      2353415 bytes
HTML transferred:       383415 bytes
Requests per second:    107.41 [#/sec] (mean)
Time per request:       931.003 [ms] (mean)
Time per request:       9.310 [ms] (mean, across all concurrent requests)
Transfer rate:          49.37 [Kbytes/sec] receivedConnection Times (ms)min  mean[+/-sd] median   max
Connect:        0    2   5.0      1      58
Processing:     5  892 2805.1     13   43782
Waiting:        5  892 2805.1     13   43781
Total:          5  894 2805.7     14   43785Percentage of the requests served within a certain time (ms)50%     1466%    13475%    44180%    80490%   242895%   446998%   903799%  13259100%  43785 (longest request)

在这里插入图片描述

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

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

相关文章

深入剖析Docker容器安全:挑战与应对策略

随着容器技术的广泛应用&#xff0c;Docker已成为现代应用开发和部署的核心工具。它通过轻量级虚拟化技术实现应用的隔离与封装&#xff0c;提高了资源利用率。然而&#xff0c;随着Docker的流行&#xff0c;其安全问题也成为关注焦点。容器化技术虽然提供了良好的资源隔离&…

Python青少年简明教程目录

Python青少年简明教程目录 学习编程语言时&#xff0c;会遇到“开头难”和“深入难”的问题&#xff0c;这是许多编程学习者都会经历的普遍现象。 学习Python对于青少年来说是一个很好的编程起点&#xff0c;相对容易上手入门&#xff0c;但语言特性复杂&#xff0c;应用较广&…

Android14 手机蓝牙配对后阻塞问题解决

Android14 手机蓝牙配对后阻塞问题解决 文章目录 Android14 手机蓝牙配对后阻塞问题解决一、前言二、手机蓝牙配对后阻塞问题解决1、部分日志&#xff1a;2、解决方法 三、其他1、Android14 蓝牙 BluetoothService 启动和相关代码介绍2、Android14 待机关机蓝牙自动关闭分析解决…

4.C_数据结构_队列

概述 什么是队列&#xff1a; 队列是限定在两端进行插入操作和删除操作的线性表。具有先入先出(FIFO)的特点 相关名词&#xff1a; 队尾&#xff1a;写入数据的一段队头&#xff1a;读取数据的一段空队&#xff1a;队列中没有数据&#xff0c;队头指针 队尾指针满队&#…

FPGA与Matlab图像处理之直方图均衡化

文章目录 一、什么是直方图?二、什么是直方图均衡化&#xff1f;三、Matlab实现直方图均衡化的步骤第一步&#xff1a; 彩色图像转成灰度图像第二步&#xff1a;提取亮度通道的直方图第三步&#xff1a;累计亮度通道的像素值频率第四步&#xff1a; 映射到新的灰度值 四、Veri…

docker挂载宿主机文件run命令启动报错

背景 使用docker安装mysql8,docker run 命令提示报错 命令: docker run -d \ -p 3306:3306 \ -v ~/docker/mysql8/log/mysqld.log:/var/log/mysqld.log \ -e MYSQL_ROOT_PASSWORD=123456 \ --name mysql8 mysql:8.0.36 报错信息 docker: Error response from daemon: fai…

嵌入式 开发技巧和经验分享

文章目录 前言嵌入式 开发技巧和经验分享目录1.1嵌入式 系统的 定义1.2 嵌入式 操作系统的介绍1.3 嵌入式 开发环境1.4 编译工具链和优化1.5 嵌入式系统软件开发1.6 嵌入式SDK开发2.1选择移植的系统-FreeRtos2.2FreeRtos 移植步骤2.3 系统移植之中断处理2.4系统移植之内存管理2…

【java面经】Redis速记

目录 基本概念 string hash list set zset 常见问题及解决 缓存穿透 缓存击穿 缓存雪崩 Redis内存管理策略 noeviction allkeys-lru allkeys-random volatile-random volatile-ttl Redis持久化机制 RDB快照 AOF追加文件 Redis多线程特性 Redis应用场景 缓…

《C++移动语义:解锁复杂数据结构的高效之道》

在 C的编程世界中&#xff0c;移动语义是一项强大的特性&#xff0c;它能够在处理复杂数据结构如链表、树等时&#xff0c;极大地提高程序的性能和效率。理解并正确实现移动语义在这些复杂数据结构中&#xff0c;对于开发者来说至关重要。 一、移动语义简介 C11 引入了移动语…

【医学半监督】置信度指导遮蔽学习的半监督医学图像分割

摘要: 半监督学习(Semi-supervised learning)旨在利用少数标记数据和多数未标记数据训练出高性能模型。现有方法大多采用预测任务机制,在一致性或伪标签的约束下获得精确的分割图,但该机制通常无法克服确认偏差。针对这一问题,本文提出了一种用于半监督医学图像分割的新…

【梯度下降|链式法则】卷积神经网络中的参数是如何传输和更新的?

【梯度下降|链式法则】卷积神经网络中的参数是如何传输和更新的&#xff1f; 【梯度下降|链式法则】卷积神经网络中的参数是如何传输和更新的&#xff1f; 文章目录 【梯度下降|链式法则】卷积神经网络中的参数是如何传输和更新的&#xff1f;1. 什么是梯度&#xff1f;2.梯度…

2024-04-23 人工智能增强天基通信和传感

砺道智库2024-04-23 11:18 北京 据国家防务网4月19日报道&#xff0c;随着商业卫星、军事星座及其所有数据在太空中流动的数量不断增加&#xff0c;政府和行业运营商表示&#xff0c;他们正在寻求人工智能来帮助他们处理日益复杂的任务。 人工智能软件使用户能够在轨道上改变航…

饲料颗粒机全套设备有哪些机器组成

饲料颗粒机全套设备通常包括原料粉碎、混合机、制粒机、冷却器、筛分机、包装机以及配套的电气控制等多个部分组成&#xff1a;1、粉碎机&#xff1a;将各种饲料原料进行清理、去杂、破碎等预处理&#xff0c;确保原料的纯净度和适宜粒度&#xff0c;为后续加工做准备。2、混合…

【永磁同步电机(PMSM)】 5. PMSM 的仿真模型

【永磁同步电机&#xff08;PMSM&#xff09;】 5. PMSM 的仿真模型 1. 基于 Simulink 的仿真模型1.1 PMSM 的数学模型1.2 Simulink 仿真模型1.3 模块封装&#xff08;mask&#xff09;1.4 三相PMSM矢量控制仿真模型 2. Simscape 的 PMSM 模块2.1 PMSM 模块的配置2.2 PMSM 模块…

系统架构设计师:软件架构的演化和维护

简简单单 Online zuozuo: 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo :本心、输入输出、结果 简简单单 Online zuozuo : 文章目录 系统架构设计师:软件架构的演化和维护前言软件架构演化的重要性面向对象的软件架构演…

数据结构与算法学习day22-回溯算法-分割回文串、复原IP地址、子集

一、分割回文串 1.题目 131. 分割回文串 - 力扣&#xff08;LeetCode&#xff09; 2.思路 分割回文串可以抽象为一棵树形结构。 递归用来纵向遍历&#xff0c;for循环用来横向遍历&#xff0c;切割线&#xff08;就是图中的红线&#xff09;切割到字符串的结尾位置&#xf…

数据库DDL语句

目录 1. 引言 2. DDL基础知识 3. 常用DDL语句 3.1 CREATE语句 示例&#xff1a;创建表 3.2 ALTER语句 示例&#xff1a;添加列 示例&#xff1a;修改字段类型 3.3 DROP语句 示例&#xff1a;删除表 3.4 TRUNCATE语句 示例&#xff1a;清空表 4. DDL与DML的区别 区…

WIFI路由器的套杆天线简谈

❝本次推文简单介绍下WIFI路由器的套杆天线。 路由器天线 路由器在这个万物互联的时代&#xff0c;想必大家对其都不陌生。随着科技的发展&#xff0c;常用的路由器上的天线也越来越多&#xff0c;那么问题来了&#xff1a;天线越多&#xff0c;信号越好吗&#xff1f;路由器…

文件系统设计 - 开发文件系统 Store (上篇)

本节开始&#xff0c;我们将从最核心基础的文件系统进行设计实现&#xff0c;构建文件系统Store 一个基础的响应式Store类设计文件系统类接口小结 一个基础的响应式Store类 从Vue3 开始&#xff0c;Vue响应式借助Proxy重构后&#xff0c;整个响应式系统的应用变得非常的灵活&a…

vue2:树形控件el-tree中加载两种不同结构的数据

需求 需要在树形控件中逐级显示公司、部门以及不同部门下的项目信息。其中&#xff0c;公司及部门信息的结构是一致的&#xff0c;但是项目是另一种结构&#xff08;类&#xff09;。所以&#xff0c;树结构中需要用到两种不同结构的数据。 El-tree 主要属性 下面是一个el-…