分析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.xdnf.cn/news/146313.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【JavaEE】——线程的安全问题和解决方式

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯&#xff0c;你们的点赞收藏是我前进最大的动力&#xff01;&#xff01;希望本文内容能够帮助到你&#xff01; 目录 一&#xff1a;问题引入 二&#xff1a;问题深入 1&#xff1a;举例说明 2&#xff1a;图解双线程计算…

springboot数字化超市管理系统—计算机毕业设计源码34804

摘 要 在网络信息的时代&#xff0c;众多的软件被开发出来&#xff0c;给用户带来了很大的选择余地&#xff0c;而且人们越来越追求更个性的需求。在这种时代背景下&#xff0c;超市只能以用户为导向&#xff0c;按品种小批量组织生产&#xff0c;以产品的持续创新作为超市最重…

ONES 与华为云深度合作,共同打造企业智能研发管理平台

9月20日&#xff0c;在华为全联接大会&#xff08;HUAWEI CONNECT 2024&#xff09;上&#xff0c;深圳复临科技有限公司&#xff08;以下简称“ONES”&#xff09;与华为云计算技术有限公司&#xff08;以下简称“华为云”&#xff09;正式签署合作协议&#xff0c;双方将在企…

Python | Leetcode Python题解之第421题数组中两个数的最大异或值

题目&#xff1a; 题解&#xff1a; class Trie:def __init__(self):# 左子树指向表示 0 的子节点self.left None# 右子树指向表示 1 的子节点self.right Noneclass Solution:def findMaximumXOR(self, nums: List[int]) -> int:# 字典树的根节点root Trie()# 最高位的二…

【图灵完备 Turing Complete】游戏经验攻略分享 Part.6 处理器架构2 函数

新的架构来了&#xff0c;本游戏的最后一个攻略分享&#xff0c;最后汇编部分无非是对于操作码的熟练&#xff0c;硬件没有问题&#xff0c;那么也就无关痛痒了。 汇编实现&#xff0c;两数相或和两数相与非一起相与即可。 八位异或器&#xff0c;整就完事了。 有手就行。 利…

十七、RC振荡电路

振荡电路 1、振荡电路的组成、作用、起振的相位条件以及振荡电路起振和平衡幅度条件&#xff0c; 2、RC电路阻抗与频率、相位与频率的关系曲线; 3、RC振荡电路的相位条件分析和振荡频率

秩一的等价转化

Lemma 2. For a positive semi-definite Hermitian matrix A ∈ C M M \mathbf{A}\in\mathbb{C}^{M\times M} A∈CMM, the condition Rank ( A ) 1 \left(\mathbf{A}\right)1 (A)1 is equivalent to t h e following conditions the\textit{ following conditions} the fol…

JavaWeb 实验一

实验一 环境配置和Web工程的创建 目的&#xff1a; 掌握Java Web编程环境的配置创建简单的Web工程&#xff0c;并了解Web工程下各目录的作用掌握部署、运行Web工程的流程 实验过程&#xff1a; 一、完成如下要求。 安装并设置JDK 1.8、Tomcat 9.0&#xff08;tomcat和jdk版…

PDF转JPG神器!一键转换,轻松搞定文档分享难题

亲爱的朋友们&#xff0c;你是不是也常常被PDF文件格式所困扰&#xff1f;特别是当你想要将PDF文件转换为JPG格式时&#xff0c;是否觉得有些头大呢&#xff1f;别担心&#xff0c;今天我将向你推荐五款非常棒的PDF转JPG工具&#xff0c;它们绝对能让你的转换过程轻松愉快&…

暴力枚举算法

《啊哈&#xff01;算法》学习笔记 本博客的题目仅用暴力枚举&#xff0c;并不一定是最好的解法&#xff0c;主要是了解枚举算法 例题一&#xff1a;两方框奥数 在两个方框内填入相同的数字使得等式成立&#xff1a; 代码如下&#xff1a; for(i1;i<9;i) {if((i*103)*652…

数据结构---二叉搜索树(二叉排序树)

什么是二叉排序树 二叉搜索树又是二叉排序树&#xff0c;当我们的是一颗空树或者具有以下性质时&#xff1a; 左子树不为空&#xff0c;左子树上的值都小于我们的根节点上的值。右子树不为空时&#xff0c;右子树上的值都大于我们的根节点上的值左右子树都是二叉搜索树&#…

Java异常架构与异常关键字

1. Java异常简介 Java 异常是 Java 提供的一种识别及响应错误的一致性机制。 Java 异常机制可以使程序中异常处理代码和正常业务代码分离&#xff0c;保证程序代码更加优雅&#xff0c;并提高程 序健壮性。在有效使用异常的情况下&#xff0c;异常能清晰的回答 what, where,…

2023北华大学程序设计新生赛部分题解

时光如流水般逝去&#xff0c;我已在校园中奋战大二&#xff01;(≧▽≦) 今天&#xff0c;静静回顾去年的新生赛&#xff0c;心中涌起无尽感慨&#xff0c;仿佛那段青春岁月如烟花般绚烂。✧&#xff61;(≧▽≦)&#xff61;✧ 青春就像一场燃烧的盛宴&#xff0c;激情澎湃&…

《高等代数》线性相关和线性无关(应用)

说明&#xff1a;此文章用于本人复习巩固&#xff0c;如果也能帮到大家那就更加有意义了。 注&#xff1a;1&#xff09;线性相关和线性无关的证明方法中较为常用的方法是利用秩和定义来证明。 2&#xff09;此外&#xff0c;线性相关和线性无关的证明常常也会用到反证法。 3&…

2.5 数据库索引机制

我们往数据表里面保存数据记录越来越多&#xff0c;一旦达到上千万条&#xff0c;那怎么提高检索速度就需要认真考虑了。我们打开手机上的APP都希望能快些加载出内容&#xff0c;这里的因素有很多&#xff0c;但是如何减少数据查找的时间是其中的重要一环。索引机制就是提升数据…

怎么给视频加字幕?6种给视频加字幕最简单的方法,不怕你学不会!

在这个快节奏的时代&#xff0c;越来越多的人会在公共场所观看视频&#xff0c;但为了不影响其它人&#xff0c;大多数人往往会将声音关闭。统计数据显示&#xff0c;高达69%的人在这样的环境中会静音观看视频&#xff0c;而有字幕的情况下&#xff0c;80%的人更倾向于完整观看…

刷题训练之栈

> 作者&#xff1a;დ旧言~ > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;熟练掌握字符串算法。 > 毒鸡汤&#xff1a;学习&#xff0c;学习&#xff0c;再学习 ! 学&#xff0c;然后知不足。 > 专栏选自&#xff1a;刷题…

C++之spring

C之spring string类对象的访问及遍历操作 operator[] 返回pos位置的字符&#xff0c;const string类对象调用 这是一个既可以写也可以读的库函数&#xff0c;const修饰的内容是不可以更改的&#xff0c;所以是读 C类与对象里要想普通对象和const修饰的对象同时重载 第二种访…

2024华为杯研究生数学建模,代码思路和参考文章

F题X射线脉冲星光子到达时间建模&#xff0c; E题高速公路应急车道紧急启用模型&#xff0c; D题大数据驱动的地理综合问題&#xff0c; C题数据驱动下磁性元件的磁芯损耗建模&#xff0c; B题W LAN 组网中网络吞吐量建模&#xff0c; A题风电场有功功率优化分配&#xff…

Python画笔案例-057 绘制蜘蛛网

1、绘制蜘蛛网 通过 python 的turtle 库绘制 蜘蛛网&#xff0c;如下图&#xff1a; 2、实现代码 绘制蜘蛛网&#xff0c;以下为实现代码&#xff1a; """蜘蛛网.py """ import turtledef draw_circle(pos,r):"""pos:圆的中心点…