一、简介
ShedLock主要用于多个相同服务在分布式环境下执行同一定时任务时,确保只有一个服务执行,即保证同一时刻,同一定时任务只被执行一次。可以通过JDBC数据库、Redis、Mongo、Hazelcast、ZooKeeper等实现锁的功能。
下面以jdbc实现锁功能为例
二、引入依赖
<!-- https://mvnrepository.com/artifact/net.javacrumbs.shedlock/shedlock-spring -->
<dependency>
<groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-spring</artifactId>
<version>4.29.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/net.javacrumbs.shedlock/shedlock-provider-jdbc-template -->
<dependency>
<groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-provider-jdbc-template</artifactId>
<version>4.23.0</version>
</dependency>
三、创建表
CREATE TABLE shedlock(
name VARCHAR(64) ,
lock_until TIMESTAMP(3) NULL,
locked_at TIMESTAMP(3) NULL,
locked_by VARCHAR(255),
PRIMARY KEY (name)
)
name:锁的名称
lock_until:释放锁时间
locked_at: 获取锁时间
locked_by:锁持有者,默认为主机名
四、配置锁
@Configuration
@EnableSchedulerLock(defaultLockAtMostFor = "PT5M")
public class ShedLockConfiguration {
/**
* 创建数据库LockProvider
*/
@Bean
public LockProvider lockProvider(DataSource dataSource) {
return new JdbcTemplateLockProvider(dataSource);
}
}
五、参数说明
@SchedulerLock注解主要参数:
name:锁的名称,必须保证唯一;
lockAtMostFor:成功执行任务的节点所能拥有的独占锁的最长时间,设置的值要保证比定时任务正常执行完成的时间大一些;
lockAtLeastFor:成功执行任务的节点所能拥有的独占锁的最短时间,其主要目的是任务执行时间可能很短,防止多个节点执行。
@EnableSchedulerLock注解主要参数:
defaultLockAtMostFor:lockAtMostFor的默认时间;
defaultLockAtLeastFor:lockAtLeastFor的默认时间。
六、测试
@EnableScheduling
public class ShedLockTest {
@Scheduled(cron = "0/30 * * * * ?")
@SchedulerLock(name = "schedule", lockAtMostFor = "10", lockAtLeastFor = "5s")
public void SynchronousSchedule() {
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("执行了一次定时任务");
}