资讯动态

看门狗(watch dog)

发布时间:2026/11/9 7:20:09 来源:尧图企业网站定制
Redis 本身原生没有看门狗机制。看门狗Watch Dog是 Redisson 实现分布式锁时自带的自动续期机制不是 Redis 服务端命令。Redis 原生分布式锁SET key value NX EX ttl锁设置固定过期时间默认30s如果业务执行时间 锁过期时间 → 锁自动释放并发安全失效。看门狗解决什么问题问题场景加锁设置过期时间 30s业务代码执行很慢GC、IO 阻塞、慢查询超过 30s 还没执行完、没释放锁Redis 自动把锁删掉其他线程拿到同一把锁 →锁失效并发问题看门狗目标只要持有锁的业务线程还没释放锁就持续延长锁的有效期防止锁提前过期。底层原理Redisson不是全靠 LuaLua 只是【锁判断、续期、释放】这些原子操作的载体看门狗整体整套逻辑大量是 Java 客户端代码底层使用引入 redisson 依赖创建 RedissonClient 客户端。redissonClient.getLock(lockKey)获取 RLock 分布式锁可重入。lock()无参开启看门狗自动续期带 leaseTime 参数看门狗关闭锁到期自动释放。tryLock()尝试抢锁只传等待时间开看门狗等待 持有时间都传则关闭看门狗。业务放 try 里finally 中先判断isHeldByCurrentThread()再 unlock防止别的线程解锁报错。底层加锁、续期、解锁靠 Lua 保证原子看门狗是客户端 Netty 定时任务。宕机后看门狗停止锁到时间自动释放不会死锁。public class RedissonSimpleDemo { // 引入redisson依赖创建RedissonClient客户端 public static RedissonClient getRedissonClient() { Config config new Config(); config.useSingleServer() .setAddress(redis://127.0.0.1:6379); return Redisson.create(config); } public static void main(String[] args) throws InterruptedException { RedissonClient redissonClient getRedissonClient(); String lockKey business:lock; // redissonClient.getLock(lockKey) 获取RLock分布式锁可重入 //RLock在Redis是Hash结构 RLock lock redissonClient.getLock(lockKey); try { // lock()无参开启看门狗自动续期 lock.lock(); System.out.println(执行业务); TimeUnit.SECONDS.sleep(35); } finally { // finally中先判断isHeldByCurrentThread()再unlock防止别的线程解锁报错 if (lock.isHeldByCurrentThread()) { lock.unlock(); } } // tryLock()尝试抢锁只传等待时间开看门狗 boolean tryLockResult false; RLock lock2 redissonClient.getLock(lockKey); try { tryLockResult lock2.tryLock(10, TimeUnit.SECONDS); if (tryLockResult) { System.out.println(tryLock执行业务); TimeUnit.SECONDS.sleep(25); } } finally { if (tryLockResult lock2.isHeldByCurrentThread()) { lock2.unlock(); } } // tryLock()等待持有时间都传则关闭看门狗 boolean tryLockResult2 false; RLock lock3 redissonClient.getLock(lockKey); try { tryLockResult2 lock3.tryLock(10,15, TimeUnit.SECONDS); if (tryLockResult2) { System.out.println(指定leaseTime执行业务看门狗关闭); TimeUnit.SECONDS.sleep(20); } } finally { if (tryLockResult2 lock3.isHeldByCurrentThread()) { lock3.unlock(); } } redissonClient.shutdown(); } }tryLock()尝试抢锁不会一直阻塞死等抢到返回 true锁重入了field计数1否则返回 false有两种常用重载tryLock(waitTime, TimeUnit)最多等待 waitTime 时间抢锁抢到就持有开启看门狗tryLock(waitTime,leaseTime, TimeUnit)最多等 waitTime抢到之后锁最多持有 leaseTime关闭看门狗不会自动续期waitTime愿意花多久等锁leaseTime锁的有效期误区锁重入关闭看门狗指的是本次加锁不开启看门狗还是说锁重入之前那次加的锁的看门狗也关闭重入不会把之前已经启动的看门狗关掉只是这次重入这一次不会再额外新建一个看门狗。unlock()释放当前线程持有的这把分布式锁。底层走 Lua 脚本hash 重入计数减一计数到 0 就删除锁 key同时停止看门狗定时任务⚠️ 只能自己解自己的锁别的线程去 unlock 会报错所以代码里要配合isHeldByCurrentThread()判断复习try放需要执行的业务代码加锁后的逻辑正常跑、或者抛出异常都会往下走finally无论 try 里面正常结束、还是抛异常、还是 returnfinally 代码几乎一定会执行Redisson 的锁结构不是简单 string是hash 结构key锁名称field当前线程唯一 IDvalue重入计数支持可重入锁好处可以精准判断这把锁是不是当前这个线程持有的防止续别人的锁豆包讲全流程

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑