Redisson的锁重试和WatchDog机制

Redisson 的分布式锁流程图可以看成"获取锁"和"释放锁"两个流程,中间由 WatchDog 续命机制串联起来。下面按图逐步解释

一、获取锁流程(左半部分)

  1. 尝试获取锁
  • Redisson 会用 Lua 脚本在 Redis 中抢锁(SETNX + Hash 结构记录线程标识)。

2.判断 TTL 是否为 null

  • 如果 Redis 返回的 TTL(锁剩余时间)是 null,说明锁当前没有设置过期时间或已经过期,继续判断 leaseTime。

3.分支:leaseTime 是否为 -1

  • leaseTime = -1:表示用户没有指定锁的过期时间。Redisson 会启动 WatchDog 定时任务,自动给锁续命(默认 30 秒,每 30/3=10 秒续一次),直到业务释放锁。
  • leaseTime != -1:用户指定了过期时间(比如 10 秒),Redisson 会直接把 TTL 设置为 10 秒,不开启 WatchDog。

4.判断剩余等待时间是否 > 0

  • 如果 tryLock 传了 waitTime,表示允许等待;Redisson 会订阅一个释放锁的消息(基于 Redis Pub/Sub),进入等待。
  • 如果没有等待时间或者已经超时,就返回 false,表示加锁失败。

二、释放锁流程(右半部分)

  1. 尝试释放锁
  • 调用 unlock() 时,Redisson 同样用 Lua 脚本判断"锁是不是自己加的"。如果不是,记录异常。

2.判断释放是否成功

  • 成功:发送"锁已释放"的消息给其他等待者,并取消 WatchDog。
  • 失败:说明锁已经过期或被别人释放,记录异常日志,流程结束。

三、WatchDog 机制(图中红色块)

  • WatchDog 是 Redisson 的自动续期机制;只有在 leaseTime = -1 时才会启动。
  • 它每隔 internalLockLeaseTime / 3 秒检查锁是否还被当前线程持有,如果还在,就再次设置 TTL(默认 30 秒)。
  • 一旦 unlock() 成功或线程崩溃,WatchDog 会停止,锁不再续期,自然在 TTL 后释放,避免死锁。

四、leaseTime = -1 的含义

  • leaseTime 是 Redisson 的锁持有时间。如果显式传入一个正数(如 10 秒),锁不会自动续命,到期后自动释放。
  • 当 leaseTime = -1(默认值)时:
  1. Redisson 认为业务不知道会执行多久,需要自动续期。
  2. 每次加锁后都会启动 WatchDog,默认 TTL=30 秒。
  3. WatchDog 每 10 秒检查一次,如果业务还没释放锁,就把 TTL 重置为 30 秒。
  4. 一旦 unlock() 或线程挂掉,WatchDog 停止,锁在 30 秒后自然释放。

简单说:

  • leaseTime = -1 → 启动 WatchDog,自动续命,适合执行时间不确定的任务。
  • leaseTime = 固定值 → 不启动 WatchDog,锁在固定时间后自动释放,适合短任务或明确控制时间。

五、整体小结

  • Redisson 获取锁时,会根据 leaseTime 判断是否需要 WatchDog,并支持等待重试。
  • WatchDog 负责给没指定过期时间的锁续命,保证业务执行期间锁不会提前释放。
  • 释放锁时会发送通知、取消 WatchDog,整个流程由 Lua 脚本保证原子性,避免并发问题。

确实挺绕的。你可以先记住两个点,先用再慢慢补细节:

  1. lock.tryLock():抢不到就等一会,抢到了就执行;等太久就返回 false(自己决定是否重试)。
  2. 不传过期时间(默认 leaseTime = -1)时,Redisson 会自动给你"锁续命",确保业务没跑完锁不会过期;自己手动指定时间时就像普通 setnx,到点自动释放。

先把这俩记住,用起来其实就是 lock.tryLock() + unlock(),其余流程是 Redisson 帮你兜底的。用了几次心里就有数了,别一次把所有细节都背下来

相关推荐
嘻哈baby4 小时前
Redis高可用部署与集群管理实战
数据库·redis·bootstrap
Java爱好狂.6 小时前
Java面试Redis核心知识点整理!
java·数据库·redis·分布式锁·java面试·后端开发·java八股文
阿杆7 小时前
如何在 Spring Boot 中接入 Amazon ElastiCache
java·数据库·redis
此生只爱蛋12 小时前
【Redis】String 字符串
java·数据库·redis
青云交12 小时前
Java 大视界 -- 基于 Java+Flink 构建实时电商交易风控系统实战(436)
java·redis·flink·规则引擎·drools·实时风控·电商交易
破烂pan12 小时前
Python 整合 Redis 哨兵(Sentinel)与集群(Cluster)实战指南
redis·python·sentinel
SoleMotive.13 小时前
redis和mysql有什么区别,以及redis和mysql都有什么缺点,以及什么地方redis不如mysql?
数据库·redis·mysql
锥锋骚年14 小时前
golang 开发 Redis与Memory统一接口方案
开发语言·redis·golang
bafuka14 小时前
别再手撸热点缓存了:一个注解搞定Redis热点问题(已开源)
redis
程可爱14 小时前
详解Redis的五种基本数据类型(String、List、Hash、Set、ZSet)
redis