028-86922220

建站动态

根据您的个性需求进行定制 先人一步 抢占小程序红利时代

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

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

创新互联是一家专业提供海门企业网站建设,专注与成都做网站、网站建设、H5网站设计、小程序制作等业务。10年已为海门众多企业、政府机构等服务。创新互联专业网络公司优惠进行中。

一、前言

关于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中分布式锁如何解决锁超时问题,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注创新互联行业资讯频道。


本文标题:Redis中分布式锁如何解决锁超时问题
本文路径:http://www.tsicrk.com/article/ipehgh.html

其他资讯

让你的专属顾问为你服务

1.1521s