ShedLock 简介
ShedLock 是一个轻量级分布式锁库,用于确保定时任务在分布式环境中仅执行一次。通过锁机制,防止多个实例同时运行同一任务。
添加依赖
在 pom.xml 中引入 ShedLock 的 Spring Boot Starter 和数据库驱动(以 JDBC 为例):
XML
<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 为例):
sql
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 并指定锁提供者:
java
@Configuration
@EnableScheduling
@EnableSchedulerLock(defaultLockAtMostFor = "PT30S")
public class SchedulerConfig {
@Bean
public LockProvider lockProvider(DataSource dataSource) {
return new JdbcTemplateLockProvider(dataSource);
}
}
defaultLockAtMostFor:定义锁的默认最大持有时间(如 30 秒)。
使用注解标记定时任务
在定时任务方法上添加 @SchedulerLock 注解:
java
@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)检查锁状态。