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

相关文章

如何解决idea的Module:‘:app‘platform‘android-32‘not found.问题

《如何解决idea的Module:‘:app‘platform‘android-32‘notfound.问题》:本文主要介绍如何解决idea的Module:‘:app‘platform‘andr... 目录idea的Module:‘:app‘pwww.chinasem.cnlatform‘android-32

kali linux 无法登录root的问题及解决方法

《kalilinux无法登录root的问题及解决方法》:本文主要介绍kalilinux无法登录root的问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,... 目录kali linux 无法登录root1、问题描述1.1、本地登录root1.2、ssh远程登录root2、

SpringBoot应用中出现的Full GC问题的场景与解决

《SpringBoot应用中出现的FullGC问题的场景与解决》这篇文章主要为大家详细介绍了SpringBoot应用中出现的FullGC问题的场景与解决方法,文中的示例代码讲解详细,感兴趣的小伙伴可... 目录Full GC的原理与触发条件原理触发条件对Spring Boot应用的影响示例代码优化建议结论F

深入理解Apache Kafka(分布式流处理平台)

《深入理解ApacheKafka(分布式流处理平台)》ApacheKafka作为现代分布式系统中的核心中间件,为构建高吞吐量、低延迟的数据管道提供了强大支持,本文将深入探讨Kafka的核心概念、架构... 目录引言一、Apache Kafka概述1.1 什么是Kafka?1.2 Kafka的核心概念二、Ka

MySQL 中查询 VARCHAR 类型 JSON 数据的问题记录

《MySQL中查询VARCHAR类型JSON数据的问题记录》在数据库设计中,有时我们会将JSON数据存储在VARCHAR或TEXT类型字段中,本文将详细介绍如何在MySQL中有效查询存储为V... 目录一、问题背景二、mysql jsON 函数2.1 常用 JSON 函数三、查询示例3.1 基本查询3.2

Java中Date、LocalDate、LocalDateTime、LocalTime、时间戳之间的相互转换代码

《Java中Date、LocalDate、LocalDateTime、LocalTime、时间戳之间的相互转换代码》:本文主要介绍Java中日期时间转换的多种方法,包括将Date转换为LocalD... 目录一、Date转LocalDateTime二、Date转LocalDate三、LocalDateTim

Redis在windows环境下如何启动

《Redis在windows环境下如何启动》:本文主要介绍Redis在windows环境下如何启动的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Redis在Windows环境下启动1.在redis的安装目录下2.输入·redis-server.exe

Pyserial设置缓冲区大小失败的问题解决

《Pyserial设置缓冲区大小失败的问题解决》本文主要介绍了Pyserial设置缓冲区大小失败的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录问题描述原因分析解决方案问题描述使用set_buffer_size()设置缓冲区大小后,buf

resultMap如何处理复杂映射问题

《resultMap如何处理复杂映射问题》:本文主要介绍resultMap如何处理复杂映射问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录resultMap复杂映射问题Ⅰ 多对一查询:学生——老师Ⅱ 一对多查询:老师——学生总结resultMap复杂映射问题

java实现延迟/超时/定时问题

《java实现延迟/超时/定时问题》:本文主要介绍java实现延迟/超时/定时问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java实现延迟/超时/定时java 每间隔5秒执行一次,一共执行5次然后结束scheduleAtFixedRate 和 schedu