☰
【Redis进阶篇|第五篇】WatchDog解决分布式锁的续期问题
2026/10/15 13:42:32 网站建设 项目流程

1. 引言

在分布式系统中,分布式锁是保障多节点互斥访问共享资源的关键手段。然而,一个经典难题始终困扰着开发者:锁的续期问题。当业务执行时间超过锁的预设有效期时,锁会自动释放,导致其他节点趁虚而入,引发数据不一致的问题。本文将深入讲解如何通过Watchdog(看门狗)机制优雅地解决这一难题。

2. 分布式锁续期问题的本质

以 Redis 分布式锁为例,通常使用SET key value NX EX seconds命令加锁,并设置一个过期时间(如 30 秒)。但业务逻辑的执行时长往往不可控,往往会出现一些突发的状况,比如说这个线程突然宕机了,但是它过了一会又恢复正常了,再比如这个线程一直在执行任务,但是任务还没执行完过期时间就到了,这就会导致任务的丢失,进而导致数据的不一致问题出现,这在要求数据强一致的情况下会造成很大的后果:

  • 如果业务在 30 秒内未执行完,锁自动过期,其他线程可获取锁,造成并发冲突。严重则会导致数据的不一致,原有的数据被进行覆盖,第一个线程和第二个线程的顺序会造成不一样的结果。
  • 如果锁的过期时间设置过长,一旦持有锁的节点宕机,锁无法及时释放,造成死锁。从而会导致整个系统进入一个死机的状态,假如这是一个秒杀专场,有一个线程抢到了这个锁,此时它如果一直就待在那个界面什么也不干,那此时其他人只能一直等待,这样的话这个服务也会出现一个很大的问题,几乎就是不可用的状态,只有等这个线程释放之后,其他线程才有机会获取到这个锁进行秒杀的活动,这对用户和企业来说都是一个毁灭性打击。

因此,核心矛盾在于:锁的过期时间无法与业务执行时长精确匹配。而 Watchdog 机制正是为了解决这一矛盾而生。

3. Watchdog 机制的核心原理

Watchdog 的本质是一个后台守护线程,它在锁持有期间持续工作,核心逻辑如下:

  1. 在获取锁成功后,启动一个定时任务(守护线程)。这个时间可以由我们控制,建议设置在3秒钟左右,也就是这个看门狗每三秒钟会看一下这个线程有没有出现问题,如果没有问题那么就将锁的过期时间进行重置。
  2. 该线程每隔一段时间(通常为锁过期时间的 1/3)检查锁是否仍然被当前线程持有。
  3. 如果锁仍然持有,则自动将锁的过期时间重置(续期),继续延长锁的生命周期。
  4. 当业务执行完毕、主动释放锁时,守护线程随之终止。

通过这种方式,即使我们设置的过期时间很短,只要我们的线程在工作,我们的看门狗就会感知到,随后将时间进行重置,这样就不会导致任务还没执行完,但时间已经到了。同样的即使我们的过期时间设置的很长,这个线程如果没有活动,那么这个看门狗也能在很短的时间内发现并且将这个线程释放,这样一来就不会造成后续的阻塞问题,服务也能够正常的运行,不会出现有人占着线程不做事的情况。

4. 代码示例:基于 Redisson 的 Watchdog 实现

在 Java 生态中,Redisson 已经内置了成熟的 Watchdog 机制。以下是一个典型的使用示例:

import org.redisson.Redisson; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.redisson.config.Config; public class WatchdogDemo { public static void main(String[] args) throws InterruptedException { // 1. 创建 Redisson 客户端 Config config = new Config(); config.useSingleServer().setAddress("redis://127.0.0.1:6379"); RedissonClient client = Redisson.create(config); // 2. 获取分布式锁(默认 leaseTime 为 -1,启用 Watchdog) RLock lock = client.getLock("myLock"); // 3. 加锁(不指定 leaseTime 时,Watchdog 自动生效) lock.lock(); try { // 模拟长时间业务执行(例如 40 秒,超过默认 30 秒锁超时) System.out.println("业务开始执行..."); Thread.sleep(40000); System.out.println("业务执行完成,锁仍然有效!"); } finally { // 4. 释放锁(Watchdog 线程随之停止) lock.unlock(); } client.shutdown(); } }

在上述代码中,调用lock.lock()且不指定leaseTime时,Redisson 会自动启用 Watchdog。默认锁超时时间为 30 秒,Watchdog 每 10 秒检查并续期一次,确保业务执行期间锁始终有效。

5. Watchdog 续期流程详解

为了更直观地理解 Watchdog 的工作流程,可以参考以下时序描述:

sequenceDiagram participant A as 业务线程 participant W as Watchdog线程 participant R as Redis A->>R: 获取锁(SET NX EX 30s) R-->>A: 加锁成功 A->>W: 启动守护线程 loop 每 10 秒 W->>R: 检查锁是否仍持有 R-->>W: 仍持有 W->>R: 续期(重置为 30s) end A->>R: 业务完成,释放锁 W-->>A: 守护线程终止

6. 手动实现一个简易 Watchdog

如果不想依赖 Redisson,也可以手动实现一个简易的 Watchdog。以下是一个基于 ScheduledExecutorService 的示例:

import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class SimpleWatchdog { private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); private volatile boolean running = true; public void startWatchdog(Runnable renewTask, long initialDelay, long period) { scheduler.scheduleAtFixedRate(() -> { if (running) { renewTask.run(); // 执行续期操作 } }, initialDelay, period, TimeUnit.SECONDS); } public void stopWatchdog() { running = false; scheduler.shutdown(); } public static void main(String[] args) throws InterruptedException { SimpleWatchdog watchdog = new SimpleWatchdog(); // 模拟续期操作:重置 Redis 锁的过期时间 Runnable renewTask = () -> System.out.println("锁已续期,重置过期时间为 30 秒"); // 启动 Watchdog,每 10 秒续期一次 watchdog.startWatchdog(renewTask, 10, 10); // 模拟业务执行 40 秒 Thread.sleep(40000); // 业务完成,停止 Watchdog watchdog.stopWatchdog(); System.out.println("业务完成,Watchdog 已停止"); } }

7. Watchdog 的注意事项与最佳实践

虽然 Watchdog 机制解决了续期问题,但在实际应用中仍需注意以下几点:

  • 续期时间间隔:建议设置为锁过期时间的 1/3,留足网络延迟和任务调度的余量,避免续期失败导致锁提前过期。
  • 网络分区风险:如果持有锁的节点发生网络分区,Watchdog 无法续期,锁最终会过期释放。此时应结合业务幂等性设计,避免重复执行造成数据错误。
  • 锁的可重入性:Redisson 的锁支持可重入,Watchdog 在续期时会维护重入计数,确保同一线程多次加锁不会导致续期错乱。
  • 避免长事务:虽然 Watchdog 能无限续期,但过长的锁持有时间会阻塞其他节点。建议将大任务拆分为多个小任务,缩短单次锁持有时间。
  • 主动释放:业务执行完毕后务必在finally块中释放锁,避免 Watchdog 无限续期造成死锁。

8. 总结

Watchdog 机制通过后台守护线程动态续期,巧妙地解决了分布式锁过期时间与业务执行时长不匹配的问题。无论是使用 Redisson 等成熟中间件,还是手动实现简易版本,理解其核心原理都至关重要。在实际项目中,建议优先采用经过生产验证的 Redisson 方案,并结合业务幂等性设计,构建高可用的分布式锁体系。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询