Redisson-lock看门狗原理
8. 分布式锁和同步器 · redisson/redisson Wiki · GitHub
默认-1

传入自己的时间(此处为10) 不会执行看门狗,不等于-1,如果是默认的话,等于-1

进入tryLockInnerAsync,发现直接执行脚本
<T> RFuture<T> tryLockInnerAsync(long waitTime, long leaseTime, TimeUnit unit, long threadId, RedisStrictCommand<T> command) {
return this.evalWriteAsync(this.getRawName(), LongCodec.INSTANCE, command, "if (redis.call('exists', KEYS[1]) == 0) then redis.call('hincrby', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then redis.call('hincrby', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; return redis.call('pttl', KEYS[1]);", Collections.singletonList(this.getRawName()), new Object[]{unit.toMillis(leaseTime), this.getLockName(threadId)});
}


protected RFuture<Boolean> renewExpirationAsync(long threadId) {
return this.evalWriteAsync(this.getRawName(), 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.singletonList(this.getRawName()), this.internalLockLeaseTime, this.getLockName(threadId));
}
- 锁的自动续期,如果业务超长,运行时间自动给锁续上新的
30秒。不用担心业务时间长。 - 加锁的任务只要运行完成,就不会给当前锁续期,即使不手动删锁。锁默认
30秒后删除
lock.lock(10, TimeUnit.SECONDS);
10秒钟自动解锁,自动解锁时间一定要大于业务时间
问题:lock.lock();在锁时间到了以后,不会自续期
-
1、如果我们传递了锁的超时时间,就发送给
redis脚本,进行占锁,默认超时时间就是我们设置的时间 -
2、如果我们未指定锁的超时时间,就使用
30*1000(LockWatchdogTimeout看门狗的默认时间);
只要占锁成功,leaseTime=-1就会启动一个定时任务- [重新给锁设置过期时间,新的过期时间就是看门狗的默认时间
30s],每隔10s都会自动续期30s
internalLockLeaseTime(看门狗时间)/3,10s
- [重新给锁设置过期时间,新的过期时间就是看门狗的默认时间
@ResponseBody
@GetMapping("/hello")
public String hello(){
//1、获取一把锁,只要锁的名字一样,就是同一把锁
RLock lock = redissonClient.getLock("myLock");
//2、加锁
lock.lock();//阻塞式等待,没拿到锁,一直等待。默认加锁30秒
//最佳实战
// lock.lock(10, TimeUnit.SECONDS);//10秒钟自动解锁,自动解锁时间一定要大于业务时间
// 省掉了整个续期操作。手动解锁
try {
System.out.println("加锁成功,执行业务"+Thread.currentThread().getId());
Thread.sleep(30000);
} catch (InterruptedException e) {
} finally {
//3、解锁,假设解锁代码没有运行,redisson会不会出现死锁
System.out.println("释放锁"+Thread.currentThread().getId());
lock.unlock();
}
return "hello";
}

本文详细解析了Redisson分布式锁的tryLockInnerAsync和renewExpirationAsync方法,介绍了如何通过设置超时时间和看门狗机制实现自动续期,以及lock.lock()函数的解锁策略。重点讨论了锁的默认30秒过期时间和10秒自动解锁策略。
1899

被折叠的 条评论
为什么被折叠?



