Redisson的看门狗机制

发布时间:2026/9/11 16:26:06

Redisson的看门狗机制 ​​​​​​​Redisson的看门狗机制原理Redisson看门狗机制相关背景Redis分布式锁的看门狗机制是Redisson为解决‌业务执行时间超过锁过期时间、锁提前释放引发并发安全问题‌设计的自动续期机制。下图展示了Redisson看门狗机制的核心运行流程flowchart TD A[业务线程调用 lock() 或 tryLock()] -- B{是否指定 leaseTime?} B -- 是 -- C[手动指定过期时间 看门狗不生效] B -- 否 -- D[获取锁成功 设置初始TTL30秒] D -- E[启动看门狗定时任务] E -- F{定时检查每10秒} F -- 锁仍被当前线程持有 -- G[执行Lua脚本续期 重置TTL为30秒] G -- F F -- 锁已释放或线程不持有 -- H[停止续期] C -- I[业务执行完成] D -- I I -- J[调用 unlock() 释放锁] J -- K[看门狗任务终止] L[客户端进程宕机] -- M[看门狗任务终止] M -- N[锁在最后一次续期后30秒自动过期]流程说明获取锁业务线程调用lock()或tryLock()且不指定leaseTime时Redisson会为锁设置默认30秒的初始TTL。启动定时任务后台立即启动基于Netty时间轮的看门狗定时任务。定期检查与续期每10秒TTL的1/3检查一次锁状态。若锁仍被当前线程持有则通过Lua脚本原子性地将锁的TTL重置为30秒。循环续期只要业务未完成且未调用unlock()续期动作就会持续循环防止锁过期。停止条件业务正常完成调用unlock()释放锁看门狗任务立即终止。客户端进程宕机看门狗任务随之终止锁在最后一次续期后30秒自动过期避免永久死锁。Redisson看门狗机制相关背景Redis分布式锁的看门狗机制是Redisson为解决‌业务执行时间超过锁过期时间、锁提前释放引发并发安全问题‌设计的自动续期机制。1. 核心生效前提只有调用tryLock()时未手动指定锁的租约时间传入leaseTime-1看门狗才会自动启动若手动设置了过期时间Redisson会认为用户自行管控锁生命周期不会触发看门狗逻辑。2. 基础运行原理锁初始化时默认给锁设置‌30秒‌的初始TTL该默认值可通过配置修改。后台启动基于Netty时间轮的轻量定时任务每10秒默认TTL的1/3检查一次锁状态若锁仍被当前线程持有就通过Lua脚本将锁的过期时间重置为30秒。只要业务线程未执行完、未调用unlock()释放锁续期动作就会循环持续避免锁提前过期。3. 停止续期的触发条件业务正常执行完成主动调用unlock()删除锁看门狗任务直接终止。客户端进程宕机看门狗定时任务随之终止锁会在最后一次续期后的30秒自动过期释放不会出现永久死锁。4. 底层实现细节看门狗的续期逻辑通过Lua脚本原子执行先校验锁是否仍被当前线程持有确认后再重置过期时间避免误续其他线程持有的锁保证续期操作的线程安全。Spring Boot 整合 Redis 实现看门狗机制完整示例1. 环境准备Maven 依赖dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-redis/artifactId /dependency dependency groupIdorg.redisson/groupId artifactIdredisson-spring-boot-starter/artifactId version3.27.0/version /dependencyapplication.yml 配置spring: redis: host: localhost port: 6379 # 密码如有 # password: yourpassword redisson: 单节点配置 single-server-config: address: redis://${spring.redis.host}:${spring.redis.port} # 连接池大小 connection-pool-size: 64 # 连接最小空闲数 connection-minimum-idle-size: 24 # 连接超时时间毫秒 connect-timeout: 10000 # 命令等待超时时间毫秒 timeout: 30002. Redisson 配置类import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.config.Config; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; Configuration public class RedissonConfig { Value(${spring.redis.host}) private String redisHost; Value(${spring.redis.port}) private int redisPort; Bean public RedissonClient redissonClient() { Config config new Config(); // 使用单节点模式 config.useSingleServer() .setAddress(redis:// redisHost : redisPort) // 看门狗默认锁超时时间毫秒默认 30000 .setLockWatchdogTimeout(30000) // 连接池配置 .setConnectionPoolSize(64) .setConnectionMinimumIdleSize(24) .setConnectTimeout(10000) .setTimeout(3000); return Redisson.create(config); } }3. 分布式锁服务类import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.concurrent.TimeUnit; Service public class DistributedLockService { Autowired private RedissonClient redissonClient; /** 获取锁启用看门狗自动续期 param lockKey 锁的key return 锁对象 */ public RLock lockWithWatchdog(String lockKey) { RLock lock redissonClient.getLock(lockKey); // 不传 leaseTime 或传 -1看门狗自动生效 lock.lock(); return lock; } /** 尝试获取锁启用看门狗自动续期 param lockKey 锁的key param waitTime 等待时间秒 return 是否获取成功 */ public boolean tryLockWithWatchdog(String lockKey, long waitTime) throws InterruptedException { RLock lock redissonClient.getLock(lockKey); // leaseTime 传 -1看门狗自动生效 return lock.tryLock(waitTime, -1, TimeUnit.SECONDS); } /** 获取锁手动指定过期时间不启用看门狗 param lockKey 锁的key param leaseTime 锁的持有时间秒到期自动释放 return 锁对象 */ public RLock lockWithLeaseTime(String lockKey, long leaseTime) { RLock lock redissonClient.getLock(lockKey); // 指定 leaseTime看门狗不生效 lock.lock(leaseTime, TimeUnit.SECONDS); return lock; } /** 释放锁 param lock 锁对象 */ public void unlock(RLock lock) { if (lock ! null lock.isLocked() lock.isHeldByCurrentThread()) { lock.unlock(); } } }4. 业务使用示例import org.redisson.api.RLock; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.concurrent.TimeUnit; Service public class OrderService { Autowired private DistributedLockService lockService; private static final String ORDER_LOCK_PREFIX order:lock:; /** 创建订单使用看门狗保证长任务锁安全 */ public void createOrderWithWatchdog(Long orderId) { String lockKey ORDER_LOCK_PREFIX orderId; RLock lock null; try { // 获取锁看门狗自动续期 lock lockService.lockWithWatchdog(lockKey); // 或者使用 tryLock同样启用看门狗 // boolean locked lockService.tryLockWithWatchdog(lockKey, 5); // if (!locked) { // throw new RuntimeException(获取锁失败); // } // 模拟耗时业务操作可能超过30秒 TimeUnit.SECONDS.sleep(40); System.out.println(订单创建成功订单ID: orderId); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new RuntimeException(订单创建被中断, e); } finally { // 释放锁看门狗任务终止 lockService.unlock(lock); } } /** 快速操作手动指定过期时间不启用看门狗 */ public void quickOperation(Long resourceId) { String lockKey resource:lock: resourceId; RLock lock null; try { // 获取锁10秒后自动过期 lock lockService.lockWithLeaseTime(lockKey, 10); // 快速业务操作 TimeUnit.SECONDS.sleep(5); System.out.println(快速操作完成资源ID: resourceId); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new RuntimeException(操作被中断, e); } finally { // 锁会在10秒后自动释放也可手动释放 lockService.unlock(lock); } } }5. 测试控制器import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; RestController public class LockTestController { Autowired private OrderService orderService; /** 测试看门狗机制 */ GetMapping(/order/create/{orderId}) public String createOrder(PathVariable Long orderId) { try { orderService.createOrderWithWatchdog(orderId); return 订单创建成功订单ID: orderId; } catch (Exception e) { return 订单创建失败: e.getMessage(); } } /** 测试手动过期锁 */ GetMapping(/resource/operate/{resourceId}) public String operateResource(PathVariable Long resourceId) { try { orderService.quickOperation(resourceId); return 资源操作成功资源ID: resourceId; } catch (Exception e) { return 资源操作失败: e.getMessage(); } } }6. 关键配置说明lockWatchdogTimeout看门狗检查间隔默认30000毫秒30秒。看门狗会在锁过期前1/3时间10秒进行检查和续期。leaseTime参数调用lock(leaseTime, unit)或tryLock(waitTime, leaseTime, unit)时如果leaseTime 0看门狗不生效如果leaseTime -1或不传看门狗生效。锁释放业务完成后必须调用unlock()否则看门狗会持续续期直到进程终止。7. 注意事项看门狗机制只在使用Redisson的RLock接口且未指定leaseTime时生效。确保Redis连接稳定网络波动可能导致续期失败锁提前释放。生产环境建议配置Redis哨兵或集群模式提高可用性。监控锁的持有时间避免业务逻辑异常导致锁长期占用。
延伸阅读

更多相关文章

2026/9/11 16:25:26

不同系统下设置静态IP

虽然所有 Linux 系统在底层的内核操作是相同的(临时配置都可以用 ip 或 ifconfig),但让静态 IP 永久生效的配置文件格式、路径以及后台网络管理服务,在不同操作系统中截然不同。各大常见系统设置静态 IP 的机制对比与操作示例说明…

2026/9/11 16:22:38

免密码进行SSH连接、Mac远程连接windows系统(拷贝本地文件)

文章目录 前言 I 免密码进行SSH连接 1.1 创建 rsa 1.2 配置 ssh config 1.3 测试连接 1.4 案例: 配置GitHub SSH keys II 远程连接windows系统。 2.1 Mac远程连接windows 2.2 windows远程连接windows 2.3 RustDesk开源远程桌面访问解决方案 III see also 移除私钥密码(Passph…

2026/9/11 16:22:37

DS18B20在ESP32上的单总线时序实现与优化

简介:面向ESP32开发者的DS18B20数字温度传感器驱动源码包,适用于智能家居、农业环境监测、工业过程控制等物联网测温场景。DS18B20支持高精度单总线通信,仅需一根数据线即可与ESP32的GPIO连接,电源与数据线供电方式灵活&#xff0…

2026/9/11 16:22:37

3步本地部署Duix.Avatar数字人视频生成工具

3步本地部署Duix.Avatar数字人视频生成工具 【免费下载链接】Duix-Avatar 🚀 Truly open-source AI avatar(digital human) toolkit for offline video generation and digital human cloning. 项目地址: https://gitcode.com/GitHub_Trending/he/Duix-Avatar …

2026/9/11 16:17:37

QGIS与Cesium瓦片地图集成开发指南

1. QGIS与Cesium瓦片地图数据集成概述在GIS开发领域,QGIS作为开源地理信息系统代表工具,与Cesium这一领先的Web三维地图引擎的协同使用正成为行业趋势。最近在完成一个智慧城市项目时,我需要将Cesium的二维瓦片地图服务集成到QGIS桌面环境中进…

2026/9/10 16:39:38

超人会飞不算本事:系统稳定依赖清晰规则与边界设计

开头先不绕弯子。“#斯坦李吐槽dc 所以超人是无缘无故会飞的嘛哈哈哈哈哈哈哈锤哥真是技术人才啊!#雷神 #复联”这类调侃式短标题,第一波冲击力在于它把两个宇宙的角色塞进同一个吐槽箱里,但细想一下就能发现,它真正碰到的根本不是…

2026/9/10 11:16:38

超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论

把“蜘蛛侠 vs 超人”放在 CSDN 上聊,可能很多人第一反应是走错片场了。但如果把这两个角色看成“两个持续运营了 80 多年的文化产品”,你会发现,这场比较本质上是两个不同 IP 策略的长期结果对比:超人赢在定义了整个超级英雄题材…

2026/9/9 16:31:09

基于CNN的调制信号识别:MATLAB实现时频图分类实战

简介:本资源是一套面向通信工程与信号处理方向学习者、研究者的深度学习实践方案,聚焦调制信号自动检测与识别这一典型无线通信任务,解决传统方法依赖人工特征、低信噪比下性能下降等痛点。压缩包共12个文件(10.73MB)&…

2026/9/10 12:32:02

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/10 15:19:50

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/10 15:49:53

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码