Redisson 分布式锁“看门狗”自动续期源码解剖

一、概述

  • 目标:围绕 Redisson 自动续期(Watchdog),进行“核心类+核心方法+行级解析”重构版技术博客,帮助从“懂原理”进阶到“懂源码+懂设计”。
  • 主线:两个核心类+三大关键方法,串起“加锁→启动看门狗→周期续期→取消续期”的完整闭环。
  • 方法:源码行级解析+时序图+架构图+设计模式+工程实践+面试速记口。

二、简介与项目背景

  • 痛点:固定 TTL 下,业务线程不可预估阻塞或崩溃,可能出现“锁尚在用却过期”的并发隐患。
  • 方案:Redisson 看门狗自动续期,持锁线程存活期间定期延长 TTL,避免误过期。
  • 触发条件:未指定租约(leaseTime=-1)时,自动启动看门狗。

三、核心类

四、核心代码:行级解析(2 类 3 法)

1)入口触发:lock()

2)看门狗启动入口:tryAcquireAsync(...)

3)看门狗启动核心:scheduleExpirationRenewal(long threadId)

4)周期续期核心:renewExpiration()

5)异步续期原子实现:renewExpirationAsync(long threadId)

6)续期状态对象:ExpirationEntry

五、可视化(颜色与样式优化)

1)主流程图(Mermaid)

ttl=null

= -1

true

false/异常

ttl>=0

加锁入口 调用 `lock()`

`tryAcquire/tryAcquireAsync`

判断 `leaseTime`

`scheduleExpirationRenewal(threadId)` 注册状态

`renewExpiration()` 创建 Netty TimerTask

到期回调 `run()`

`renewExpirationAsync(threadId)` EVAL Lua

`cancelExpirationRenewal` 停止续期

返回 TTL 或重试等待

2)时序图(Mermaid)

Redis Netty Timer RedissonLock 业务线程 Redis Netty Timer RedissonLock 业务线程 alt [res=true] [res=false] `lock()`(leaseTime=-1) `tryAcquire/tryAcquireAsync` ttl=null(加锁成功) `scheduleExpirationRenewal(threadId)` `newTimeout(TimerTask, watchdog/3)` 到期回调 `run()` `renewExpirationAsync(threadId)` EVAL Lua res=true/false `renewExpiration()`(递归下一轮) `cancelExpirationRenewal(threadId)`

六、设计模式点睛

七、工程实践与边界

  • 节奏:watchdog=30s,续期周期=10s(1/3);可调 Config.setLockWatchdogTimeout(...)
  • 场景选择:不确定耗时/可能阻塞→看门狗;确定性短事务→固定 leaseTime
  • 故障语义:线程崩溃或连接异常→续期停止,锁在窗口后自动过期。
  • 观测性:采集续期成功/失败/取消次数与回调异常;压测 EventLoop 负载与时间轮稳定性。

八、面试速记口

  • 口诀一:lock(-1) 启动看门狗;tryAcquire 成功→schedulerenewExpiration 定时 Lua pexpire 递归。
  • 口诀二:时间轮 O(1);回调驱动;Map 共享;Lua 原子。
  • 口诀三:模板钩子+命令封装+观察回调+享元缓存+适配器联动 Netty。
  • 口诀四:成功递归、失败取消;线程崩溃自动过期;leaseTime>0 禁看门狗。

九、权威资料与参考

十、总结

  • 看门狗以“Netty 时间轮+Lua 原子续期+状态表共享”保障持锁期间不误过期。
  • 两类三法串起核心路径,设计模式提升稳定性与可扩展性。
  • 实战策略:不确定耗时用看门狗;确定性短事务用固定租约;完善告警与压测。
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐