Redisson分布式锁与Watch dog机制解读

本文详细介绍了Redisson分布式锁的工作原理及其实现机制。重点解释了watchdog自动延期机制如何防止锁死,并讨论了锁的续期过程以及锁释放异常情况下的行为。

在这里插入图片描述

Redisson锁的加锁机制如图所示 线程去获取锁 获取成功则执行lua脚本 保存数据到redis数据库

如果获取失败: 一直通过while循环尝试获取锁(可自定义等待时间 超时后返回失败)

Redisson提供的分布式锁是支持锁的自动续期的, 也就是说 如果线程仍然没有执行完毕 那么redisson会自动给redis中的目标key延长超时时间 这在redisson中称之为watch dog机制 默认续30秒

watch dog自动延期机制

如果拿到分布式锁的节点宕机 且这个锁正好处于锁住的状态时, 会出现锁死的情况 为了避免这种情况发生 锁都会设置一个过期时间 这样也存在一个问题 当业务时间过长时 达到了超时时间的还没有结束的话 会释放锁 就会导致问题 Redisson中添加了watch dog机制来解决这个问题 自动延期机制

它的作用是在Redisson的实例被关闭前,不断地延长锁的有效期 也就是说 如果一个拿到锁的线程一直没有完成逻辑 那么看门口会帮助线程不断地延长超时时间

另外Redisson还提供了可以指定leaseTime参数的加锁方法来指定加锁的时间 超过这个时间后锁便自动解开了 不会延长锁的有效期

关键结论

  • watch dog 在当前节点存活时 每10s给分布式锁的key续期30s
  • watch dog机制启动 且代码中没有释放锁的操作时 watch dog会不断给锁续期
  • 如果程序释放锁操作因为异常没有执行 那么锁无法被释放 所以释放锁操作一定要放到finally{}

但是如果释放锁的操作本身异常了 watch dog 还会不停的续期吗?

不会 因为无论释放锁操作是否成功 EXPIRATION_RENEWAL_MAP中的目标ExpirationEntry对象已经被移除了 watch dog通过判断后就不会继续给锁续期了

Java中实现Redis分布式悲观锁可以采用以下两种常见方式: ### 基于Jedis客户端实现 可以参考一篇全面讲解利用JavaRedis实现分布式锁的文章,该文章涵盖了从项目背景、理论基础、实现思路到完整代码、详细注释、代码解读及项目总结等内容,其中详细描述了基于Jedis客户端的分布式锁加锁、解锁及续期机制。不过文档未给出具体代码,一般实现思路如下: ```java import redis.clients.jedis.Jedis; public class RedisPessimisticLockByJedis { private static final String LOCK_KEY = "distributed_lock"; private static final String LOCK_VALUE = "lock_value"; private static final int EXPIRE_TIME = 10; // 锁的过期时间,单位:秒 private Jedis jedis; public RedisPessimisticLockByJedis() { this.jedis = new Jedis("localhost", 6379); } public boolean lock() { // 使用SETNX命令尝试加锁 String result = jedis.set(LOCK_KEY, LOCK_VALUE, "NX", "EX", EXPIRE_TIME); return "OK".equals(result); } public void unlock() { // 释放锁 jedis.del(LOCK_KEY); } } ``` ### 基于Redisson框架实现 Redisson是一个在Redis的基础上实现的Java驻内存数据网格,它提供了丰富的功能,包括分布式锁的支持,目前是最流行的Redis分布式锁实现方式。Redisson提供了分布式锁的封装方法,只需要调用API中的`lock()`和`unlock()`方法即可,同时内置了Watch Dog机制来对key做续期,避免死锁发生。示例代码如下: ```java import org.redisson.Redisson; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.redisson.config.Config; public class RedisPessimisticLockByRedisson { private static final String LOCK_KEY = "distributed_lock"; private RedissonClient redissonClient; public RedisPessimisticLockByRedisson() { Config config = new Config(); config.useSingleServer().setAddress("redis://localhost:6379"); this.redissonClient = Redisson.create(config); } public void lock() { RLock lock = redissonClient.getLock(LOCK_KEY); lock.lock(); } public void unlock() { RLock lock = redissonClient.getLock(LOCK_KEY); lock.unlock(); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值