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);

redisson-lock1

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

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

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

redisson-lock

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

总结

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

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

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容