Redisson看门狗机制与锁租期配置详解

小豆丁 21小时前 ⋅ 9 阅读
聊天记录
头像

// 方案2:不使用看门狗(适合短时间固定业务) lock.tryLock(waitTime, 30, TimeUnit.SECONDS);

// 方案3:完全禁用看门狗(明确业务执行时间) lock.tryLock(waitTime, 10, TimeUnit.SECONDS); 这个不是完全一样的

头像

你说得对,这两行代码在逻辑上完全一致,只是参数值不同。我的注释确实造成了误解。让我重新澄清:

Redisson 的看门狗机制规则

核心规则:

只有两种情况会启用看门狗

  1. 不指定 leaseTime 参数(使用两个参数的 tryLock
  2. 指定 leaseTime = -1

其他情况(指定任何正的 leaseTime 值)都不会启用看门狗

正确对比:

JAVA
// 方案A:使用看门狗机制(自动续期)
lock.tryLock(waitTime, -1, TimeUnit.SECONDS);  // 或 lock.tryLock(waitTime, TimeUnit.SECONDS)

// 方案B:禁用看门狗机制(固定租期)
lock.tryLock(waitTime, 30, TimeUnit.SECONDS);  // 30秒后自动过期,不续期

更明确的分类示例:

1. 使用看门狗(自动续期)

JAVA
// 方式1:两个参数方法,默认启用看门狗
lock.tryLock(3, TimeUnit.SECONDS);

// 方式2:三个参数,显式设为-1
lock.tryLock(3, -1, TimeUnit.SECONDS);
  • 看门狗默认30秒超时
  • 每10秒自动续期一次
  • 适用于执行时间不确定的业务
  • 必须手动解锁,否则锁会一直存在

2. 禁用看门狗(固定租期)

JAVA
// 固定租期10秒
lock.tryLock(3, 10, TimeUnit.SECONDS);

// 固定租期30秒  
lock.tryLock(3, 30, TimeUnit.SECONDS);

// 固定租期60秒
lock.tryLock(3, 60, TimeUnit.SECONDS);
  • 无论设多少秒,都不启用看门狗
  • 指定时间后自动释放
  • 适用于执行时间可预估的业务
  • 即使不手动解锁,也会在租期后自动释放

代码示例对比:

JAVA
public class LockExample {
    /**
     * 使用看门狗(自动续期)
     * 适合:长时间任务,如定时任务处理大量数据
     */
    public void processWithWatchdog() {
        RLock lock = redisson.getLock("long-task");
        try {
            if (lock.tryLock(3, -1, TimeUnit.SECONDS)) {
                // 长时间任务,看门狗会每10秒自动续期
                processLongTask();  // 可能执行几分钟
            }
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }
    
    /**
     * 禁用看门狗(固定租期)
     * 适合:短时间确定性任务
     */
    public void processWithoutWatchdog() {
        RLock lock = redisson.getLock("short-task");
        try {
            // 最多等待1秒,锁定3秒后自动释放
            if (lock.tryLock(1, 3, TimeUnit.SECONDS)) {
                processShortTask();  // 保证3秒内完成
                // 可以不手动解锁,3秒后会自动释放
            }
        } catch (Exception e) {
            // 即使业务异常,锁也会在3秒后自动释放
        }
    }
}

重要区别总结:

特性 使用看门狗 (leaseTime=-1) 禁用看门狗 (leaseTime>0)
自动续期 ✅ 是,每10秒自动续期 ❌ 否,固定时间后过期
默认超时 30秒 自定义的 leaseTime
适用场景 执行时间不确定的任务 执行时间可预估的短任务
释放要求 必须手动解锁 可手动解锁,也会自动过期
防死锁 需确保finally中解锁 有超时保护,但仍建议解锁
网络故障 看门狗停止续期,锁在30秒后释放 锁在 leaseTime 后释放

最佳实践建议:

  1. 不确定执行时间的业务,使用看门狗,并在finally中确保解锁:

    JAVA
    lock.tryLock(waitTime, -1, TimeUnit.SECONDS);
    
  2. 确定短时间的业务,使用固定租期:

    JAVA
    // 根据业务最长时间设置,通常加一些缓冲
    int estimatedTime = 5;  // 预估5秒完成
    int buffer = 2;         // 2秒缓冲
    lock.tryLock(waitTime, estimatedTime + buffer, TimeUnit.SECONDS);
    

感谢指出,之前注释的表述确实容易引起误解。核心是:任何正数的 leaseTime 都会禁用看门狗,只有 -1 或不指定时才启用

全部评论: 0

    我有话说: