Redis分布式锁过期时间续约问题

2024-01-05 18:40

本文主要是介绍Redis分布式锁过期时间续约问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Redis实现分布式锁的自动续时间问题

  • Redis实现分布式锁的自动续命问题
    • 首先了解lua脚本,原子性。
    • HashedWheelTimer时间轮异步定时执行
    • Redis通过异步定时使用lua脚本重置分布式锁的过期时间

Redis实现分布式锁的自动续命问题

首先了解lua脚本,原子性。

lua脚本在Redis中是原子性的,就是在执行lua脚本的时候,不会被其他外部命令干扰,但是不能回滚,结果错就是错了,结果没有回滚一说。

HashedWheelTimer时间轮异步定时执行

HashedWheelTimer的demo使用演示

package com.lxx;import io.netty.util.HashedWheelTimer;
import io.netty.util.Timeout;import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;public class shiyan {//HashedWheelTimer异步执行static SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");public static void main(String[] args) {Date date = new Date(System.currentTimeMillis());System.out.println(formatter.format(date));testTimeout();System.out.println("结束吧");//现在又想取消掉这个任务
//        if(!newTimeout.isExpired()){
//            newTimeout.cancel();
//        }}public static void testTimeout() {HashedWheelTimer timer = new HashedWheelTimer();
//        timer.newTimeout(new TimerTask() {
//            @Override
//            public void run(Timeout timeout) throws Exception {
//                Date datee = new Date(System.currentTimeMillis());
//                System.out.println("10s后执行" + formatter.format(datee));
//            }
//        }, 10, TimeUnit.SECONDS);Timeout newTimeout = timer.newTimeout(timerTask -> {Date datee = new Date(System.currentTimeMillis());System.out.println("10s后执行" + formatter.format(datee));testTimeout();//回调自己,在进行10s执行一次。}, 10, TimeUnit.SECONDS);//10s后执行Lambda表达式/*现在又想取消掉这个任务if (!newTimeout.isExpired()) {newTimeout.cancel();}*/}
}

执行结果:
在这里插入图片描述

Redis通过异步定时使用lua脚本重置分布式锁的过期时间

使用StringRedisTemplate,因为使用的序列化问题。不建议使用RedisTemplate,如果使用,要改序列化。可自行搜索。

package com.lxx;import io.netty.util.HashedWheelTimer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.Arrays;
import java.util.concurrent.TimeUnit;@RestController
@RequestMapping("shiyan")
public class RedisSuo {@Autowiredprivate StringRedisTemplate redisTemplate;//lua脚本如果有当前key那么就去重置当前key的过期时间返回1,否则返回0。private static String luas = "if (redis.call('exists',KEYS[1]) == 1) then redis.call('expire',KEYS[1], ARGV[1]) return 1 end return 0";private static DefaultRedisScript luaaa = new DefaultRedisScript(luas, Boolean.class);//讲lua脚本封装到类中private HashedWheelTimer timer = new HashedWheelTimer();private String key = "suo";@RequestMapping("select")public Boolean selectById(String valueid, int time) {//redis底层执行的是SET K V NX EX 60Boolean status = redisTemplate.opsForValue().setIfAbsent(key, valueid, time, TimeUnit.SECONDS);//加锁以及超时时间if (status) {try {//核心是异步多长时间后执行就可以。watchdog(time);//执行业务代码Thread.sleep(15 * 1000);} catch (Exception e) {throw new RuntimeException(e.getMessage());} finally {//释放锁资源。底层就是DEL kredisTemplate.delete(key);}return true;} else {System.out.println("服务器正忙请稍后再试..........");return false;}}public void watchdog(int time) {timer.newTimeout(timerTask -> {Boolean execute = (Boolean) redisTemplate.execute(luaaa, Arrays.asList(key), String.valueOf(time));//意思就是执行luaaa,key给KEYS[1],time给ARGV[1]if (execute) {System.out.println("如果当前的key有,并且已经续期了,那么现在需要递归判断下一次是否还有key。");watchdog(time);} else {System.out.println("没有key了。锁已经没了,就不会进行续期了");}}, time / 3, TimeUnit.SECONDS);//time的三分之一时间去执行看有没有key,有重置过期时间,没有就什么都不做。}
}

请求,时间为30s。代码里面是15s,会进行续命。
在这里插入图片描述
执行结果。进行了一次续命。
在这里插入图片描述
走到了23
在这里插入图片描述
重置续命后30
在这里插入图片描述
附上Redisson官网

在这里插入图片描述
最后用Redisson的API来实现分布式锁的应用。
结束!感谢观看!

这篇关于Redis分布式锁过期时间续约问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/573795

相关文章

Redis Cluster模式配置

《RedisCluster模式配置》:本文主要介绍RedisCluster模式配置,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录分片 一、分片的本质与核心价值二、分片实现方案对比 ‌三、分片算法详解1. ‌范围分片(顺序分片)‌2. ‌哈希分片3. ‌虚

C++ 函数 strftime 和时间格式示例详解

《C++函数strftime和时间格式示例详解》strftime是C/C++标准库中用于格式化日期和时间的函数,定义在ctime头文件中,它将tm结构体中的时间信息转换为指定格式的字符串,是处理... 目录C++ 函数 strftipythonme 详解一、函数原型二、功能描述三、格式字符串说明四、返回值五

Springboot整合Redis主从实践

《Springboot整合Redis主从实践》:本文主要介绍Springboot整合Redis主从的实例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言原配置现配置测试LettuceConnectionFactory.setShareNativeConnect

从基础到进阶详解Pandas时间数据处理指南

《从基础到进阶详解Pandas时间数据处理指南》Pandas构建了完整的时间数据处理生态,核心由四个基础类构成,Timestamp,DatetimeIndex,Period和Timedelta,下面我... 目录1. 时间数据类型与基础操作1.1 核心时间对象体系1.2 时间数据生成技巧2. 时间索引与数据

MySQL 设置AUTO_INCREMENT 无效的问题解决

《MySQL设置AUTO_INCREMENT无效的问题解决》本文主要介绍了MySQL设置AUTO_INCREMENT无效的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参... 目录快速设置mysql的auto_increment参数一、修改 AUTO_INCREMENT 的值。

关于跨域无效的问题及解决(java后端方案)

《关于跨域无效的问题及解决(java后端方案)》:本文主要介绍关于跨域无效的问题及解决(java后端方案),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录通用后端跨域方法1、@CrossOrigin 注解2、springboot2.0 实现WebMvcConfig

Redis过期删除机制与内存淘汰策略的解析指南

《Redis过期删除机制与内存淘汰策略的解析指南》在使用Redis构建缓存系统时,很多开发者只设置了EXPIRE但却忽略了背后Redis的过期删除机制与内存淘汰策略,下面小编就来和大家详细介绍一下... 目录1、简述2、Redis http://www.chinasem.cn的过期删除策略(Key Expir

Go语言中泄漏缓冲区的问题解决

《Go语言中泄漏缓冲区的问题解决》缓冲区是一种常见的数据结构,常被用于在不同的并发单元之间传递数据,然而,若缓冲区使用不当,就可能引发泄漏缓冲区问题,本文就来介绍一下问题的解决,感兴趣的可以了解一下... 目录引言泄漏缓冲区的基本概念代码示例:泄漏缓冲区的产生项目场景:Web 服务器中的请求缓冲场景描述代码

Java死锁问题解决方案及示例详解

《Java死锁问题解决方案及示例详解》死锁是指两个或多个线程因争夺资源而相互等待,导致所有线程都无法继续执行的一种状态,本文给大家详细介绍了Java死锁问题解决方案详解及实践样例,需要的朋友可以参考下... 目录1、简述死锁的四个必要条件:2、死锁示例代码3、如何检测死锁?3.1 使用 jstack3.2

解决JSONField、JsonProperty不生效的问题

《解决JSONField、JsonProperty不生效的问题》:本文主要介绍解决JSONField、JsonProperty不生效的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录jsONField、JsonProperty不生效javascript问题排查总结JSONField