介绍一下Redisson的看门狗机制

文章目录

      • [一、 核心工作原理](#一、 核心工作原理)
        • [1. 触发条件](#1. 触发条件)
        • [2. 默认参数](#2. 默认参数)
        • [3. 续期过程](#3. 续期过程)
      • [二、 如果客户端宕机了怎么办?](#二、 如果客户端宕机了怎么办?)
      • [三、 源码层面的实现逻辑](#三、 源码层面的实现逻辑)
      • [四、 优缺点分析](#四、 优缺点分析)
      • 总结

在分布式锁的实现中, Redisson 的看门狗(Watchdog)机制 是为了解决一个经典难题: "如何给锁设置一个完美的过期时间?"

如果过期时间太短,业务没执行完锁就释放了,会导致并发安全问题;如果过期时间太长(甚至不设过期时间),万一客户端宕机了,锁就会一直留在 Redis 里形成死锁。


一、 核心工作原理

看门狗的核心逻辑可以概括为:自动续期,防止提前失效。

1. 触发条件

并不是所有的 Redisson 锁都会启动看门狗。

  • 启动: 只有当你加锁时没有显式指定 leaseTime(或者设为 -1)时,看门狗才会启动。
  • 不启动: 如果你写的是 lock.lock(10, TimeUnit.SECONDS),Redisson 会认为你很清楚业务耗时,到期即删,不再续期。
2. 默认参数
  • 默认生存时间: lockWatchdogTimeout 默认为 30 秒。
  • 续期频率: 每隔 lockWatchdogTimeout / 3 的时间(即 10 秒)检查一次。
3. 续期过程

当锁成功获取后,Redisson 会在后台启动一个定时任务(基于 Netty 的 HashedWheelTimer 时间轮):

  1. 每隔 10 秒,看门狗会检查主线程是否还持有这把锁。
  2. 如果线程依然存活且未主动释放锁,它会向 Redis 发送一段 Lua 脚本。
  3. 该脚本负责将该 Key 的过期时间重新重置为 30 秒。

二、 如果客户端宕机了怎么办?

这正是看门狗机制的高明之处:

  • 自动释放: 如果持有锁的 Java 进程突然崩溃或断电,看门狗这个后台线程自然也就随之消失了。
  • 死锁预防: 此时没有人再给 Redis 里的 Key 续期,那么最多过了 30 秒(默认值),Redis 就会自动删除这个 Key,其他等待的线程就能重新竞争锁。

三、 源码层面的实现逻辑

在 Redisson 的 tryLockInnerAsync 方法中,加锁成功后会调用 scheduleExpirationRenewal:

java 复制代码
// 伪代码逻辑
private void renewExpiration() {
    // 1. 创建一个延时任务
    Timeout task = timer.newTimeout(timeout -> {
        // 2. 异步执行续期 Lua 脚本
        CompletionStage<Boolean> future = renewExpirationAsync(threadId);
        future.whenComplete((res, e) -> {
            if (res) {
                // 3. 如果续期成功,递归调用自身,实现循环续期
                renewExpiration();
            }
        });
    }, internalLockLeaseTime / 3, TimeUnit.MILLISECONDS);
}

四、 优缺点分析

优点
  • 业务解耦: 开发者不需要预估业务执行时间,避免了因 GC 抖动或网络延迟导致的锁提前失效。
  • 安全防死锁: 结合了 Redis 的 TTL 机制和存活检查。
缺点与风险
  • 性能开销: 虽然 Lua 脚本很轻量,但大量长耗时任务会导致频繁的续期网络请求。
  • 依然存在"异步复制"问题: 看门狗解决了单机 Redis 上的锁过期问题,但如果 Redis 是主从架构,Master 宕机且锁未同步到 Slave,依然可能发生锁丢失(这需要配合 Redlock 算法或使用 ZooKeeper 来解决)。

总结

看门狗就像是一个**"心跳监测器"**。它在不阻塞主业务逻辑的前提下,确保了只要你的程序还在运行,锁就永远不会过期;而一旦你的程序"断气"了,锁也能在短时间内自动归还。

在你的微服务项目中,如果涉及到长时间的任务处理(比如复杂的报表生成或跨系统的 AIGC 内容处理),看门狗是保证分布式锁可靠性的必备工具。

关于 Redisson 的锁,你是否还关注过它的公平锁或者**红锁(Redlock)**的具体应用场景?

相关推荐
源码集结号20 分钟前
云诊所门诊系统源码,基于SpringBoot+Vue.js架构,支持多租户设计与Docker容器化部署
java·spring boot·源码·医院信息系统·门诊系统·诊所系统
论文复现现场42 分钟前
WRF、FEA 能用 L40S 加速吗?求解器检查、断点恢复与长期运行
java·数据库·算法·wrf·有限元分析·gpu计算·断点续算
啃瓜子的松鼠1 小时前
泛微OAe9-后端二开异步调用
java
秋天的怀念_David2 小时前
第二十一夜 · 数字黑洞与西西弗斯的惩罚
java·程序人生·算法
外收内放2 小时前
Python基础语法练习题(73)
java·前端·python
Wang's Blog2 小时前
Java 项目实战: 交友项目 - 环信后台发送消息测试
java·交友
用户3721574261352 小时前
Java 操作 Word 脚注和尾注:添加、读取与删除
java
小嘉丶学长3 小时前
Day14 · 字典与集合
java·开发语言·网络·python·学习·1024程序员节
字节探索3 小时前
Spring Boot 接口幂等性设计:从唯一索引到 Redis+Lua 的工程实践
java·spring boot
用户3721574261353 小时前
Java 实现 Excel 与 Markdown 相互转换:表格导出、格式设置与多表提取
java