Spring Boot 整合 ShedLock 处理定时任务重复
ShedLock 简介
ShedLock 是一个轻量级分布式锁库,用于确保定时任务在分布式环境中仅执行一次。通过锁机制,防止多个实例同时运行同一任务。
添加依赖
在 pom.xml 中引入 ShedLock 的 Spring Boot Starter 和数据库驱动(以 JDBC 为例):
<dependency><groupId>net.javacrumbs.shedlock</groupId><artifactId>shedlock-spring</artifactId><version>4.44.0</version>
</dependency>
<dependency><groupId>net.javacrumbs.shedlock</groupId><artifactId>shedlock-provider-jdbc-template</artifactId><version>4.44.0</version>
</dependency>
配置数据库表
创建用于存储锁信息的表(以 MySQL 为例):
CREATE TABLE shedlock (name VARCHAR(64) PRIMARY KEY,lock_until TIMESTAMP(3) NULL,locked_at TIMESTAMP(3) NULL,locked_by VARCHAR(255)
);
配置 ShedLock
在 Spring Boot 配置类中启用 ShedLock 并指定锁提供者:
@Configuration
@EnableScheduling
@EnableSchedulerLock(defaultLockAtMostFor = "PT30S")
public class SchedulerConfig {@Beanpublic LockProvider lockProvider(DataSource dataSource) {return new JdbcTemplateLockProvider(dataSource);}
}
defaultLockAtMostFor:定义锁的默认最大持有时间(如 30 秒)。
使用注解标记定时任务
在定时任务方法上添加 @SchedulerLock 注解:
@Component
public class ScheduledTasks {@Scheduled(cron = "0 */5 * * * *") // 每5分钟执行@SchedulerLock(name = "reportTask", lockAtLeastFor = "PT5M", lockAtMostFor = "PT10M")public void generateReport() {// 任务逻辑}
}
name:锁的唯一标识,需全局唯一。lockAtLeastFor:最短锁持有时间(避免短周期任务重复)。lockAtMostFor:最大锁持有时间(超时后自动释放)。
支持的锁提供者
除 JDBC 外,ShedLock 还支持以下存储:
- MongoDB:
shedlock-provider-mongo - Redis:
shedlock-provider-redis-spring - Zookeeper:
shedlock-provider-zookeeper-curator
注意事项
- 确保数据库时区与应用一致,避免锁时间计算错误。
lockAtMostFor应大于任务执行时间,否则可能导致多实例并发执行。- 生产环境建议结合监控(如 Prometheus)检查锁状态。
