基于本文回答

播面 播面

文图音视,全方位拆解八股文
0
评论

Redisson的WatchDog机制在拿到锁的节点突然宕机时会发生什么?

知识点图片

当 Redisson 中拿到锁的节点突然宕机时,不会发生死锁

简单来说:看门狗(WatchDog)会随着节点的宕机而“死亡”,锁会在默认的 30 秒(或剩余的过期时间)后由 Redis 自动释放,其他等待的节点可以正常获取到锁。

以下是详细的运作过程和底层原理:

1. 看门狗的本质

很多开发者误以为看门狗是 Redis 服务端的功能,其实不然。看门狗是 Redisson 客户端(运行在你的业务 Java 进程中)的一个后台定时任务(底层基于 Netty 的时间轮 HashedWheelTimer 实现)。

  • 当你的应用不指定锁的超时时间去获取锁时(例如直接调用 lock.lock()),Redisson 会默认给这个锁设置一个 30 秒(lockWatchdogTimeout,可配置)的过期时间(TTL)。
  • 同时,客户端内会启动一个看门狗定时任务,每隔 10秒(30秒的 1/3)去 Redis 执行一次 Lua 脚本,把这个锁的过期时间重新重置为 30 秒。这就叫“自动续期”。

2. 节点宕机后的发生流程

如果拿到锁的节点(JVM 进程)突然宕机(断电、进程被强杀、OOM 等),会发生以下事情:

  1. 客户端进程销毁:业务节点宕机,意味着运行在其中的 JVM 进程结束。
  2. 看门狗线程死亡:由于看门狗仅仅是 JVM 里的一个后台线程,皮之不存毛将焉附,看门狗任务也随之立刻停止。
  3. 续期中断:既然看门狗死了,就不会再有任何请求发送到 Redis 去延长该锁的过期时间了。
  4. Redis 自动兜底:Redis 服务端依然保存着这个锁的 Key,但它的过期时间(TTL)在不断减少。
  5. 锁自动释放:经过最多 30 秒的时间(取决于宕机时锁剩余的 TTL),Redis 会自动将这个 Key 过期删除。
  6. 其他节点接管:其他正在阻塞等待该锁的节点,通过 Redis 的 Pub/Sub 机制收到锁释放的通知(或者通过轮询重试),进而成功抢到锁,业务继续执行。

3. 最大阻塞时间是多久?

如果宕机发生,其他节点最多会被阻塞多久?

  • 默认情况下,lockWatchdogTimeout 是 30 秒。
  • 因为看门狗每 10 秒续期一次,所以当节点突然宕机时,Redis 端这个锁的剩余存活时间一定在 20 秒 到 30 秒 之间。
  • 因此,其他节点最多等待约 30 秒,就能重新获取到锁。

补充说明:看门狗生效的前提

需要注意的是,看门狗机制并不是在所有情况下都会启动

  • 会启动看门狗: 使用无参的 lock() 或者 tryLock()
  • 不会启动看门狗: 如果你在加锁时手动指定了过期时间,例如 lock.lock(10, TimeUnit.SECONDS)。此时 Redisson 会认为你自己能够把控超时时间,不会开启看门狗。这种情况下如果节点宕机,锁会在你指定的 10 秒后由 Redis 自动释放。
00:00
00:00