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 块中释放锁。

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