首页 > 教程攻略 > ai教程 >[057][调度模块]分布式环境下定时任务的防重复执行方案

[057][调度模块]分布式环境下定时任务的防重复执行方案

来源:互联网 时间:2026-08-07 07:27:31

[057][调度模块]分布式环境下定时任务的防重复执行方案

本文章代码: gitee , gitcode , github

[057][调度模块]分布式环境下定时任务的防重复执行方案

摘要

在集群部署场景里,同一份定时任务很容易被多台机器同时拉起执行,轻则白白消耗资源,重则直接引发数据错乱。本文将围绕提供的 AutoRenewalLockTaskRunnerFixedLeaseLockTaskRunner 系列接口展开,说明怎样用 Redis/Redisson 分布式锁把任务执行过程包起来,从而保证任一时刻只会有一个节点真正执行任务。

1. 任务接口设计

框架定义了多个锁装饰器接口,业务实现只需继承相应接口并实现 doRun()

// Redis 自动续期锁public interface AutoRenewalLockTaskRunner extends TaskRunner, Lockable { @Overridedefault void run(Map params) { RedisLockService.instance.autoRenewal().doInLock(key(), () -> doRun(params));}void doRun(Map params);// key() 定义锁的标识,如 "task:order:sync"}

类似地,还提供了:

FixedLeaseLockTaskRunner(Redis 固定租期) AutoRenewalBlockLockTaskRunner(Redisson 阻塞 自动续期) FixedLeaseReentrantLockTaskRunner(Redisson 可重入 固定租期)

2. 两种锁模式对比

模式 适用场景 Redis 实现 Redisson 实现
固定租期 任务执行时间稳定且较短 SET NX PX 不续期 lock(leaseTime)
自动续期 任务执行时间不确定或较长 定时任务每 5s 续期 lock()(看门狗机制)

3. 锁的粒度控制

Lockable 接口要求实现类提供 key() 方法,通常按任务名称或业务 ID 区分:

@Overridepublic String key() { return "schedule:lock:"   getTaskName(); // 例如通过构造函数注入}

4. 异常处理

若获取锁失败(如已被其他节点占用),会抛出 LockCreateException,任务直接跳过,不会影响下次调度。 可覆盖 handleException(LockException) 方法自定义失败处理(如记录日志、发送告警)。

5. 集群效果

所有节点使用相同的锁 key,第一个获得锁的节点执行,其他节点快速失败,保证任务在集群内单点运行。