首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Redis分布式锁的看门狗续期,为什么还是会在这三种场景下失效

Redis分布式锁的看门狗续期,为什么还是会在这三种场景下失效

原创
作者头像
用户5598620
发布于 2026-10-12 16:17:01
发布于 2026-10-12 16:17:01
10
举报

导读:很多团队用Redisson加分布式锁,图的就是它有看门狗自动续期,业务不用算过期时间。但线上还是出过"锁提前释放、两个线程并发写同一份库存"的事故。这篇把看门狗续期失效的三种真实场景、复现方式和修复点写清楚,附可运行的最小复现代码。

一、先回顾看门狗到底在做什么

Redisson加锁时不指定leaseTime,默认锁30秒;后台启动一个定时任务,每10秒(过期时间的三分之一)检查一次:如果持锁线程还活着,就把锁重新续到30秒。

它的设计前提是三个:1.持锁线程还在跑、没被卡住;2.续期请求能正常打到Redis;3.锁确实还在自己手里(用唯一value判断)。下面三种失效,分别打破这三个前提中的一个。

二、场景一:业务线程被长时间阻塞,续期任务跟着停了

看门狗的续期任务,是跑在Redisson自己的调度线程池里。但如果你的业务逻辑里调用了同一个Redis连接池做阻塞操作,连接池被打满,续期命令就排不进去,30秒一到锁自动释放。最小复现:

代码语言:java
复制
RLock lock = redissonClient.getLock("order:1001");
try {
    lock.lock();
    Thread.sleep(35000);
} finally {
    lock.unlock();
}

修复点:看门狗调度池和业务Redis调用池分开;关键长任务显式指定一个足够长的leaseTime,不要完全依赖看门狗;业务方法里不要做不可控的阻塞等待。

三、场景二:GC停顿让续期"迟到",锁先过期了

看门狗每10秒续一次,看着留了20秒余量。但JVM一次Full GC停顿15秒,续期任务被挂起,等GC结束锁已经过期。这时候另一个线程加锁成功,两个线程同时进入临界区。

这不是Redisson的bug,是所有"本地调度+远程过期"方案共有的脆弱点。

修复点:关键业务监控GC停顿,STW超过3秒就要告警;锁的过期时间不要用默认30秒,按业务最大执行时间设一个保守值;临界区里的操作必须是幂等的。

四、场景三:主从切换,锁"丢"在了旧主上

这是最隐蔽的一种。线程A在主节点加锁成功,看门狗还没来得及把锁同步到从节点,主节点宕机、从节点升主。新主上根本没有这把锁,线程B过来直接加锁成功。

Redisson的看门狗解决不了主从复制的异步延迟,这是Redis主从架构下分布式锁的经典问题。

修复点:对正确性要求极高的场景,用RedLock多实例加锁;或者退一步承认锁只用于减少冲突,真正的正确性由数据库唯一约束、乐观锁、幂等键来保证;主从切换期间做好故障演练。

五、踩坑清单

  • 不要以为开了看门狗就万事大吉,它依赖本地调度和网络可达;
  • lock()不指定leaseTime才走看门狗;指定了leaseTime,看门狗直接不续期;
  • unlock()要在finally里,且判断isHeldByCurrentThread,否则会误删别人的锁;
  • 同一个锁key不要在不同JVM里用不同客户端混用,value生成规则不一致会误删;
  • 看门狗续期失败时Redisson只会打日志,默认不抛异常,要把ERROR日志接到告警。

工程落地建议

  • 先问自己:这把锁是用来绝对互斥还是减少并发冲突?后者用数据库唯一索引和乐观锁更可靠;
  • 临界区必须幂等,任何重复执行不产生脏数据;
  • 监控三个指标:锁等待时长、看门狗续期失败日志、锁持有时长分布;
  • 关键锁的过期时间按业务P99执行时间乘2设置,不要全用默认值。

上线检查清单

  • 所有关键锁的临界区操作是幂等的;
  • 锁持有时长超过过期时间一半的情况有监控告警;
  • Redis主从切换做过演练;
  • 看门狗续期失败日志接入了告警;
  • unlock在finally里且判断了持锁线程。

常见问题

Q:锁过期了但业务还在跑,会发生什么?

A:另一个线程能加锁成功,两个线程进入同一临界区。后果取决于业务是否幂等:幂等操作最坏重复一次,非幂等操作会把同一份数据写两遍。

Q:RedLock真的比单节点锁安全吗?

A:它降低了主从切换丢锁的概率,但引入了多时钟漂移和网络分区的复杂度。工程上更常见的做法是锁做粗粒度互斥,数据库做最终正确性。

Q:看门狗默认30秒、每10秒续期,能改吗?

A:能,在Redisson配置里改lockWatchdogTimeout。改之前先确认业务最大执行时间,把续期间隔和过期时间一起调。

结语

分布式锁的看门狗是个工程便利,不是正确性保证。它能挡住业务比预估慢一点的常见情况,但挡不住GC停顿、连接池阻塞、主从切换。真正的正确性,永远在临界区的幂等和数据库约束里。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 一、先回顾看门狗到底在做什么
  • 二、场景一:业务线程被长时间阻塞,续期任务跟着停了
  • 三、场景二:GC停顿让续期"迟到",锁先过期了
  • 四、场景三:主从切换,锁"丢"在了旧主上
  • 五、踩坑清单
  • 工程落地建议
  • 上线检查清单
  • 常见问题
  • 结语
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档