
Redisson 的分布式锁流程图可以看成"获取锁"和"释放锁"两个流程,中间由 WatchDog 续命机制串联起来。下面按图逐步解释
一、获取锁流程(左半部分)
- 尝试获取锁
- 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,表示加锁失败。
二、释放锁流程(右半部分)
- 尝试释放锁
- 调用 unlock() 时,Redisson 同样用 Lua 脚本判断"锁是不是自己加的"。如果不是,记录异常。
2.判断释放是否成功
- 成功:发送"锁已释放"的消息给其他等待者,并取消 WatchDog。
- 失败:说明锁已经过期或被别人释放,记录异常日志,流程结束。
三、WatchDog 机制(图中红色块)
- WatchDog 是 Redisson 的自动续期机制;只有在 leaseTime = -1 时才会启动。
- 它每隔 internalLockLeaseTime / 3 秒检查锁是否还被当前线程持有,如果还在,就再次设置 TTL(默认 30 秒)。
- 一旦 unlock() 成功或线程崩溃,WatchDog 会停止,锁不再续期,自然在 TTL 后释放,避免死锁。
四、leaseTime = -1 的含义
- leaseTime 是 Redisson 的锁持有时间。如果显式传入一个正数(如 10 秒),锁不会自动续命,到期后自动释放。
- 当 leaseTime = -1(默认值)时:
- Redisson 认为业务不知道会执行多久,需要自动续期。
- 每次加锁后都会启动 WatchDog,默认 TTL=30 秒。
- WatchDog 每 10 秒检查一次,如果业务还没释放锁,就把 TTL 重置为 30 秒。
- 一旦 unlock() 或线程挂掉,WatchDog 停止,锁在 30 秒后自然释放。
简单说:
- leaseTime = -1 → 启动 WatchDog,自动续命,适合执行时间不确定的任务。
- leaseTime = 固定值 → 不启动 WatchDog,锁在固定时间后自动释放,适合短任务或明确控制时间。
五、整体小结
- Redisson 获取锁时,会根据 leaseTime 判断是否需要 WatchDog,并支持等待重试。
- WatchDog 负责给没指定过期时间的锁续命,保证业务执行期间锁不会提前释放。
- 释放锁时会发送通知、取消 WatchDog,整个流程由 Lua 脚本保证原子性,避免并发问题。
确实挺绕的。你可以先记住两个点,先用再慢慢补细节:
- lock.tryLock():抢不到就等一会,抢到了就执行;等太久就返回 false(自己决定是否重试)。
- 不传过期时间(默认 leaseTime = -1)时,Redisson 会自动给你"锁续命",确保业务没跑完锁不会过期;自己手动指定时间时就像普通 setnx,到点自动释放。
先把这俩记住,用起来其实就是 lock.tryLock() + unlock(),其余流程是 Redisson 帮你兜底的。用了几次心里就有数了,别一次把所有细节都背下来