Skip to content

1. Redisson 分布式锁的核心机制 ​

Redisson 的分布式锁(RLock)通过 「看门狗(Watchdog)」 机制解决了锁过期时间和业务执行时间不匹配的问题,具体流程如下:

1.1 加锁与默认过期时间 ​

  • 使用 lock() 或 tryLock() 方法获取锁时,默认锁的过期时间为 30 秒。

  • 关键代码

    java
    java
    
    复制代码RLock lock = redisson.getLock("myLock");
    lock.lock();  // 默认 30 秒过期,后台启动看门狗

1.2 看门狗的工作原理 ​

  • 后台线程续期:Redisson 启动一个后台线程(看门狗),每 10 秒 检查一次锁是否仍被当前线程持有。
  • 自动续期:如果锁仍被持有,则重置锁的过期时间回到 30 秒(避免业务未完成时锁过期)。
  • 释放锁时停止续期:当调用 unlock() 时,看门狗线程会终止续期操作。

2. 如何避免业务未完成时锁过期? ​

2.1 正确使用看门狗 ​

  • 必须使用默认的 lock() 方法:若手动指定过期时间(如 lock.lock(10, TimeUnit.SECONDS)),看门狗机制会被禁用,此时需自行确保业务在过期时间内完成。

  • 推荐写法

    java
    java
    
    复制代码RLock lock = redisson.getLock("myLock");
    try {
        lock.lock();  // 启用看门狗
        // 执行业务逻辑(时间可能超过 30 秒)
    } finally {
        lock.unlock();  // 释放锁并停止看门狗
    }

2.2 锁续期流程 ​

加锁成功(默认30秒过期)
   ↓
启动看门狗线程(每10秒检查一次)
   ↓
业务执行中... 
   ↓
看门狗检测到锁仍被持有 → 重置过期时间为30秒
   ↓
业务执行完毕 → 调用 unlock() → 释放锁并终止看门狗

3. 关键设计优势 ​

3.1 避免锁提前释放 ​

  • 看门狗通过不断续期,确保只要业务线程存活且未释放锁,锁就不会过期。
  • 即使业务执行时间超过 30 秒,锁仍会持续续期,直到业务主动释放。

3.2 防止死锁 ​

  • 默认 30 秒过期兜底:如果持有锁的客户端宕机,看门狗线程终止,锁最终会在 30 秒后自动释放,避免死锁。

  • 与纯设置过期时间的区别

    • 单纯设置过期时间(如 SET key value EX 30 NX)无法处理业务超时问题。
    • Redisson 的看门狗在客户端存活时动态续期,兼顾了锁的可靠性和灵活性。

4. 其他注意事项 ​

4.1 不要手动指定过期时间 ​

  • 错误用法

    java
    java
    
    复制代码lock.lock(10, TimeUnit.SECONDS);  // 手动指定过期时间,看门狗被禁用

    若业务执行超过 10 秒,锁会提前释放,导致并发问题。

4.2 确保释放锁 ​

  • 必须将 unlock() 放在 finally 块中,防止异常导致锁未释放。
  • Redisson 的锁支持可重入性,同一线程可多次加锁,需对应数量的解锁操作。

4.3 结合业务设置合理超时 ​

  • 虽然看门狗能续期,但业务逻辑应有超时机制(如数据库查询设置超时时间),避免长时间阻塞。

5. 对比其他方案 ​

方案优点缺点
Redisson 看门狗自动续期,无需业务关心超时问题依赖 Redisson 客户端,需保持客户端存活
手动设置过期时间实现简单业务超时可能导致锁失效
基于 Lua 脚本的锁原子性操作需自行实现续期逻辑,复杂度高

总结 ​

  • Redisson 看门狗是分布式锁的“守护线程”,通过定期续期解决了锁过期与业务执行时间不匹配的问题。
  • 最佳实践:使用默认的 lock() 方法(启用看门狗),避免手动指定过期时间,并在 finally 块中释放锁。

文章来源于自己总结和网络转载,内容如有任何问题,请大佬斧正!联系我