当前位置: 首页>后端>正文

9. 缓存Redis 分布式锁的续期

Redis分布式锁比较正确的姿势是采用redisson这个客户端工具。

可重入锁(Reentrant Lock)

基于Redis的Redisson分布式可重入锁RLock。

public class DemoMain {
    public static void main(String[] args) throws Exception {
        Config config = new Config();
        config.useSingleServer().setAddress("redis://127.0.0.1:6379");

        RedissonClient redisson = Redisson.create(config);
        RLock lock = redisson.getLock("anyLock");

        lock.lock();
        ...
        //lock.unlock();
    }
}

问题分析 Redisson节点宕机&锁续期

锁超时-节点宕机

如果负责存储分布式的Redisson节点宕机,而且这个锁正好处于上锁的状态时,那么就会出现我们所谓的死锁的状态。但是为了避免这种情况的发生,Redisson内部已经提供了一种机制。可通过Redisson通过加锁的方式提供了leaseTime的参数来指定加锁的时间,超过这个时间这个锁就自动解开了。

锁续期-节点宕机

Redisson内部已经提供了一种机制,LockWatchDog(看门狗) 即提供了一个监控锁的看门狗,它的作用是在Redisson实例被关闭前,不断的延长锁的有效期。默认情况下,看门狗检查锁超时时间的间隔为30秒,这个时间可通过Config.lockWatchDogTimeout来进行指定。

Redisson.create(config);

9. 缓存Redis 分布式锁的续期,第1张
redisson-lock1

通过源码:internalLockLeaseTimelockWatchdogTimeout这两个参数是相等的.
lockWatchdogTimeout默认值如下

public class Config {
    private long lockWatchdogTimeout = 30 * 1000;
    public long getLockWatchdogTimeout() {
       return lockWatchdogTimeout;
    }
    //...
}

internalLockLeaseTime:分布式锁的超时时间默认是30秒.
看门狗,多久来延长一次有效期呢?

9. 缓存Redis 分布式锁的续期,第2张
redisson-lock

即:获取锁成功就会开启一个定时任务,也就是watchdog,定时任务会定期检查去续期renewExpirationAsync(threadId).
这里定时用的是netty-common包中的HashedWheelTimer,该定时调度每次调用的时间差是internalLockLeaseTime / 3.也就10秒.

总结

默认情况下,加锁的时间是30秒.如果加锁的业务没有执行完,那么到 30-10 = 20秒的时候,就会进行一次续期,把锁重置成30秒.那这个时候可能又有同学问了,那业务的机器万一宕机了呢?宕机了定时任务跑不了,就续不了期,那自然30秒之后锁就解开了.

注:内容总结于肥朝微信公众号,在此只是当做学习笔记-非原创


https://www.xamrdz.com/backend/34e1941443.html

相关文章: