Redis中分布式锁如何解决锁超时问题

发布时间:2021-07-29 17:38:19 作者:Leah
来源:亿速云 阅读:444

本篇文章给大家分享的是有关Redis中分布式锁如何解决锁超时问题,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

一、前言

关于redis分布式锁, 查了很多资料, 发现很多只是实现了最基础的功能, 但是, 并没有解决当锁已超时而业务逻辑还未执行完的问题, 这样会导致: A线程超时时间设为10s(为了解决死锁问题), 但代码执行时间可能需要30s, 然后redis服务端10s后将锁删除, 此时, B线程恰好申请锁, redis服务端不存在该锁, 可以申请, 也执行了代码, 那么问题来了, A、B线程都同时获取到锁并执行业务逻辑, 这与分布式锁最基本的性质相违背: 在任意一个时刻, 只有一个客户端持有锁, 即独享

二、准备工作

压测工具jmeter


https://pan.baidu.com/share/init?surl=NN0c0tDYQjBTTPA-WTT3yg提取码: 8f2a

redis-desktop-manager客户端


https://pan.baidu.com/share/init?surl=NoJtZZZOXsk45aQYtveWbQ提取码: 9bhf

postman


https://pan.baidu.com/share/init?surl=28sGJk4zxoOknAd-47hE7w提取码: vfu7

也可以直接官网下载, 我这边都整理到网盘了

需要postman是因为我还没找到jmeter多开窗口的办法, 哈哈

三、说明

1、springmvc项目

2、maven依赖

Redis中分布式锁如何解决锁超时问题

3、核心类

四、实现思路

先测试在不开启锁延时线程的情况下, A线程超时时间设为10s, 执行业务逻辑时间设为30s, 10s后, 调用接口, 查看是否能够获取到锁, 如果获取到, 说明存在线程安全性问题

同上, 在加锁的同时, 开启锁延时线程, 调用接口, 查看是否能够获取到锁, 如果获取不到, 说明延时成功, 安全性问题解决

五、实现

1、版本01代码

1)、DistributedLock

Redis中分布式锁如何解决锁超时问题

Redis中分布式锁如何解决锁超时问题

说明: 就2个方法, 加锁解锁, 加锁使用jedis setnx方法, 解锁执行lua脚本, 都是原子性操作

2)、PcInformationServiceImpl

Redis中分布式锁如何解决锁超时问题

说明: 测试类很简单, value随机生成, 保证唯一, 不会在超时情况下解锁其他客户端持有的锁

3)、打开redis-desktop-manager客户端, 刷新缓存, 可以看到, 此时是没有add_information_lock的key的

Redis中分布式锁如何解决锁超时问题

4)、启动jmeter, 调用接口测试

设置5个线程同时访问, 在10s的超时时间内查看redis, add_information_lock存在, 多次调接口, 只有一个线程能够获取到锁

往期100篇回顾:一百期面试题汇总

redis

Redis中分布式锁如何解决锁超时问题

1-4个请求, 都未获取到锁

Redis中分布式锁如何解决锁超时问题

第5个请求, 获取到锁

Redis中分布式锁如何解决锁超时问题

OK, 目前为止, 一切正常, 接下来测试10s之后, A仍在执行业务逻辑, 看别的线程是否能获取到锁

Redis中分布式锁如何解决锁超时问题

可以看到, 操作成功, 说明A和B同时执行了这段本应该独享的代码, 需要优化。

往期100篇回顾:一百期面试题汇总

2、版本02代码

1)、DistributedLock

Redis中分布式锁如何解决锁超时问题

Redis中分布式锁如何解决锁超时问题

Redis中分布式锁如何解决锁超时问题

说明: 新增了锁延时方法, lua脚本, 自行脑补相关语法

2)、PcInformationServiceImpl不需要改动

3)、PostponeTask

Redis中分布式锁如何解决锁超时问题

Redis中分布式锁如何解决锁超时问题

说明: 调用lock同时, 立即开启PostponeTask线程, 线程等待超时时间的2/3时间后, 开始执行锁延时代码, 如果延时成功, add_information_lock这个key会一直存在于redis服务端, 直到业务逻辑执行完毕, 因此在此过程中, 其他线程无法获取到锁, 也即保证了线程安全性

下面是测试结果

10s后, 查看redis服务端, add_information_lock仍存在, 说明延时成功

Redis中分布式锁如何解决锁超时问题

此时用postman再次请求, 发现获取不到锁

Redis中分布式锁如何解决锁超时问题

看一下控制台打印

Redis中分布式锁如何解决锁超时问题

Redis中分布式锁如何解决锁超时问题

A线程在19:09:11获取到锁, 在10 * 2 / 3 = 6s后进行延时, 成功, 保证了业务逻辑未执行完毕的情况下不会释放锁

A线程执行完毕, 锁释放, 其他线程又可以竞争锁

OK, 目前为止, 解决了锁超时而业务逻辑仍在执行的锁冲突问题, 还很简陋, 而最严谨的方式还是使用官方的 Redlock 算法实现, 其中 Java 包推荐使用 redisson, 思路差不多其实, 都是在快要超时时续期, 以保证业务逻辑未执行完毕不会有其他客户端持有锁

以上就是Redis中分布式锁如何解决锁超时问题,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注亿速云行业资讯频道。

推荐阅读:
  1. 如何解决redis分布式锁的问题
  2. 如何实现Redis分布式锁和解决超时问题

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

redis

上一篇:AJAX中怎么利用 CORS解决跨域

下一篇:Nginx中出现错误码如何解决

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》