redisson看门狗机制

Redisson的WatchDog机制是Redisson提供的监控锁的看门狗,它的作用是在Redisson实例被关闭前,不断的延长锁的有效期。当一个拿到锁的线程一直没有完成逻辑,那么看门狗会帮助线程不断的延长锁超时时间,锁不会因为超时而被释放。默认情况下,看门狗的续期时间是30s,也可以通过修改Config.lockWatchdogTimeout来另行指定。

关于为什么不直接设置永久有效

直接设置永久有效的话,客户端崩溃后锁得不到释放,从而产生死锁,而看门狗机制则不会。

如果持有锁的客户端因为任何原因(比如崩溃或网络中断)无法继续工作,WatchDog将不再续期,这样锁将在其剩余的有效期内自然过期,从而释放出来供其他等待的客户端获取。这种方式提高了系统的鲁棒性和资源利用率,避免了死锁问题。

相关源码

//watchDog启动
private void renewExpiration() {
    ExpirationEntry ee = EXPIRATION_RENEWAL_MAP.get(getEntryName());
    if (ee == null) {
        return;
    }

    Timeout task = commandExecutor.getConnectionManager().newTimeout(new TimerTask() {
        @Override
        public void run(Timeout timeout) throws Exception {
            ExpirationEntry ent = EXPIRATION_RENEWAL_MAP.get(getEntryName());
            if (ent == null) {
                return;
            }
            RFuture<Boolean> future = renewExpirationAsync("EXPIRE", ent.getLockName(), internalLockLeaseTime);
            future.onComplete((res, e) -> {
                if (e != null) {
                    log.error("Can't update lock " + getEntryName() + " expiration", e);
                    return;
                }

                if (res) {
                    // reschedule itself
                    renewExpiration();
                }
            });
        }
    }, internalLockLeaseTime / 3, TimeUnit.MILLISECONDS);

    ee.setTimeout(task);
}
//WatchDog的停止
private void cancelExpirationRenewal() {
    ExpirationEntry ent = EXPIRATION_RENEWAL_MAP.get(getEntryName());
    if (ent == null) {
        return;
    }

    Timeout timeout = ent.getTimeout();
    if (timeout != null) {
        timeout.cancel();
    }
    EXPIRATION_RENEWAL_MAP.remove(getEntryName());
}
//WatchDog的续期
private RFuture<Boolean> renewExpirationAsync(String command, String key, long leaseTime) {
    return commandExecutor.evalWriteAsync(key, LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,
            "if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then " +
                "redis.call('pexpire', KEYS[1], ARGV[1]); " +
                "return 1; " +
            "end; " +
            "return 0;",
            Collections.<Object>singletonList(getEntryName()), 
            leaseTime, getLockName());
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值