← 返回题目列表

Redisson 分布式锁的看门狗(watchdog)自动续期是怎么实现的?

高频 中等 第 11 / 26 题 更新于 2026/07/28
Redisson看门狗锁续期

简化版

看门狗是 Redisson 用来自动续期分布式锁的后台机制,解决「业务没执行完但锁到期了」的问题。当你用 Redisson 加锁且不指定过期时间时,Redisson 给锁一个默认 30 秒的过期时间,并启动一个后台定时任务,每隔 10 秒(过期时间的 1/3)检查一次:如果锁还被持有(业务还在跑),就把过期时间重置回 30 秒。这样只要业务不结束,锁就一直续命不过期;业务结束主动解锁、或客户端宕机(续期任务随之停止),锁才真正过期释放。

详细版

触发条件:调用 lock.lock()(不传 leaseTime)时才启用看门狗。如果 lock.lock(10, TimeUnit.SECONDS) 显式指定了过期时间,则不启用看门狗(到点就过期,需自己保证业务在时限内完成)。

核心参数

  • lockWatchdogTimeout:看门狗默认过期时间,默认 30 秒
  • 续期间隔:过期时间的 1/3,即默认 10 秒续一次。

工作流程

  1. lock() 加锁成功,锁的过期时间设为 30 秒。
  2. Redisson 启动一个定时任务(基于 Netty 的时间轮 HashedWheelTimer),10 秒后触发。
  3. 触发时用 Lua 脚本检查「锁是否仍被本客户端持有」,是则重置过期时间为 30 秒,并再安排下一次 10 秒后续期。
  4. 循环续期,直到:① 业务执行完调用 unlock()(取消续期任务、删锁);② 客户端宕机(JVM 挂了,续期任务不再执行,锁 30 秒后自然过期)。

解决的问题:既防止「锁提前过期导致并发/误删」,又防止「持锁者宕机后锁永不释放的死锁」——两者兼顾。

完整版教学

一、看门狗要解决的核心矛盾

分布式锁设过期时间是为了防死锁(持锁者宕机后锁能自动释放)。但过期时间是个两难:

  • 设短了:业务还没做完锁就过期,别人拿到锁,产生并发(这正是误删/并发的根源)。
  • 设长了:持锁者真宕机时,别人要傻等很久才能拿锁。

看门狗巧妙化解了这个矛盾:给一个不长的初始过期时间(30s,保证宕机后最多 30s 就释放),但只要持锁者还活着、业务还在跑,就自动把它续下去。于是「业务多久锁就持有多久」,同时「持锁者一挂,续期停止,最多 30s 后释放」。鱼和熊掌兼得。

二、为什么续期间隔是过期时间的 1/3

续期间隔设为过期时间的 1/3(30s → 10s),是为了留足容错余量。假设某次续期请求因网络抖动失败或延迟,还有后续两次机会(第 20s、第 30s 前)补救,不至于一次失败就让锁过期。如果续期间隔贴着过期时间(如 29s 续一次),一次网络抖动就可能错过续期导致锁过期。1/3 是安全性和续期频率的平衡。

记忆点:默认 30 秒过期、10 秒续一次(1/3)。1/3 是为了给续期失败留 2 次重试余量。

三、宕机时为什么锁能释放

关键:看门狗是持锁客户端 JVM 里的一个后台线程。如果这个 JVM 进程崩溃/被 kill,看门狗线程也随之消失,不再有人给锁续期。于是锁在最后一次续期后的 30 秒内自然过期,被 Redis 自动删除,其他客户端得以获取。这就是「宕机自动释放、防死锁」的实现——不需要额外机制,进程没了续期自然停。

四、显式指定 leaseTime 会怎样

如果调用 lock.lock(20, TimeUnit.SECONDS),明确告诉 Redisson「这锁 20 秒后过期」,Redisson 不启动看门狗,锁到 20 秒就过期,不会续期。这适合你能确定业务一定在 20 秒内完成的场景,避免看门狗的续期开销。但如果业务可能超时,就别指定 leaseTime,交给看门狗托管。二者取舍:能估准业务耗时 → 指定 leaseTime;估不准 / 可能超长 → 用看门狗

五、看门狗的注意事项

  • 不指定 leaseTime 才生效:这是最常被忽略的点,指定了过期时间看门狗就不工作。
  • 续期依赖客户端存活:如果是业务逻辑死循环(进程没死但业务卡死),看门狗会一直续期,锁永不释放——看门狗只能应对「宕机」,应对不了「进程活着但业务卡死」,这种要靠业务超时控制。
  • Redis 主从切换仍可能丢锁:看门狗解决的是「续期」,不解决「主从复制延迟 + 主宕机导致锁丢失」,那是 Redlock/ZK 的范畴。

六、常见误区与追问

这道题不能只背概念,要把「Redisson WatchDog」放回真实分布式系统里解释:谁发起、谁协调、状态如何变化、失败后怎么兜底,以及它和性能、可用性、一致性的取舍。

回答层次要讲清的内容容易漏掉的边界
核心结论WatchDog 是 Redisson 对未指定 leaseTime 的锁自动续期机制,避免业务未执行完锁过期不要停在名词解释
流程机制客户端加锁成功 -> 启动续期任务 -> 定期检查锁 owner -> 延长 TTL -> 业务完成 unlock -> 客户端宕机则停止续期并等待 TTL 过期说明触发方、参与方、状态变化和兜底
工程取舍默认锁 30 秒,持锁线程存活时每约 10 秒续期一次,直到 unlock 或客户端崩溃停止续期分布式锁只能控制临界区进入,不能替代业务幂等和状态校验
Redisson WatchDog 面试拆解:
1. 客户端加锁成功
2. 启动续期任务
3. 定期检查锁 owner
4. 延长 TTL
5. 业务完成 unlock
6. 客户端宕机则停止续期并等待 TTL 过期

记忆钩子:先说为什么单机锁失效,再说明加锁、过期、续期、解锁、防误删和故障恢复;回答时要紧扣「Redisson WatchDog」这道题,不要把相邻概念混成一段泛泛的分布式套话。

  • 误区:WatchDog 会无限保证锁安全。 它依赖客户端存活和续期成功,网络暂停或长 GC 仍可能失败。
  • 误区:指定 leaseTime 后仍自动续期。 Redisson 指定固定 leaseTime 时通常不会启用 watchdog 自动续期。
  • 误区:有续期就不需要幂等。 锁失效、重试和故障恢复仍可能重复执行。
  • 追问:WatchDog 解决什么问题? 解决业务执行时间不确定导致锁提前过期的问题。
  • 追问:默认续期时间是多少? Redisson 默认 lockWatchdogTimeout 常见为 30 秒。
  • 追问:什么时候不建议依赖 WatchDog? 超长任务、强一致临界区或网络抖动严重场景,要拆任务或用更强协调。

七、加强记忆

Redisson 看门狗是持锁客户端 JVM 里的后台定时任务,用于自动续期:lock() 不指定过期时间时,锁默认 30 秒过期,看门狗每 **10 秒(1/3)**检查并把过期时间重置回 30 秒,业务不结束锁就一直续命;业务完成解锁或客户端宕机(续期线程随之消失),锁才在 30 秒内自然过期。它同时化解了「锁提前过期导致并发」和「持锁者宕机导致死锁」的矛盾。注意:显式指定 leaseTime 则不启用看门狗;它防不了「进程活着但业务卡死」和主从丢锁。