Shedlock是一个锁,用于在分布式环境中执行定时任务。
要解决的问题:在分布式环境中如何避免多个实例在同一时间重复执行定时任务。
解决方法:对公共数据库中的某个表进行记录和加锁,保证同一时间只有第一个实例执行定时任务,其他实例直接跳过该任务。
git地址:https://github.com/lukas-krecan/ShedLock
引用依赖:
<dependency> <groupId>net.javacrumbs.shedlock</groupId> <artifactId>shedlock-spring</artifactId> <version>4.22.1</version> </dependency>
<dependency> <groupId>net.javacrumbs.shedlock</groupId> <artifactId>shedlock-provider-jdbc-template</artifactId> <version>4.22.1</version> </dependency>
创建表:
# MySQL, MariaDB CREATE TABLE shedlock(name VARCHAR(64) NOT NULL, lock_until TIMESTAMP(3) NOT NULL, locked_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), locked_by VARCHAR(255) NOT NULL, PRIMARY KEY (name)); # Postgres CREATE TABLE shedlock(name VARCHAR(64) NOT NULL, lock_until TIMESTAMP NOT NULL, locked_at TIMESTAMP NOT NULL, locked_by VARCHAR(255) NOT NULL, PRIMARY KEY (name)); # Oracle CREATE TABLE shedlock(name VARCHAR(64) NOT NULL, lock_until TIMESTAMP(3) NOT NULL, locked_at TIMESTAMP(3) NOT NULL, locked_by VARCHAR(255) NOT NULL, PRIMARY KEY (name)); # MS SQL CREATE TABLE shedlock(name VARCHAR(64) NOT NULL, lock_until datetime2 NOT NULL, locked_at datetime2 NOT NULL, locked_by VARCHAR(255) NOT NULL, PRIMARY KEY (name)); # DB2 CREATE TABLE shedlock(name VARCHAR(64) NOT NULL PRIMARY KEY, lock_until TIMESTAMP NOT NULL, locked_at TIMESTAMP NOT NULL, locked_by VARCHAR(255) NOT NULL);
注解:
@EnableSchedulerLock(defaultLockAtMostFor = "10m") // 开启定时任务锁并指定一个默认的锁的时间
@SchedulerLock(name = "scheduledTaskName", lockAtMostFor = "14m", lockAtLeastFor = "14m") // 指定锁名(主键),根据锁名判断定时任务是否已经执行
name:主键,用来识别某个定时任务
lockAtMostFor:成功执行任务的节点所能拥有独占锁的最长时间
lockAtMostForString:lockAtMostFor的字符串,例如“PT14M”表示为14分钟,单位可以是S,M,H
lockAtLeastFor:成功执行任务的节点所能拥有独占所的最短时间
lockAtLeastForString:lockAtLeastFor的字符串,例如“PT14M”表示为14分钟,单位可以是S,M,H