1、简介
ShedLocks是一个分布式定时任务锁,它能在分布式的环境下,确保任务在同一个时刻最多执行一次。比如:同一个服务部署在多台服务器上,这个服务中定义了一个定时任务,那么在任务执行的时候这些服务器上的任务都会执行,这样是不行的,定时任务只需要执行一次就行了。ShedLock的任务就是保证一个任务在一个节点执行时,它将获得一个把锁,这把锁会阻止从另一个节点执行同一任务;大概的意思就是在一个服务集群中,如果有一个节点服务器执行这个定时任务,那么其他节点服务器不会等着,而是直接跳过执行。
ShedLock可以使用Redis、MongoDB、Mysql,Zookeeper或其他外部存储进行协调,就是通过外部存储来实现锁机制。
1.2 用法
- 启用和配置计划的锁定
- 注释任务计划
- 配置锁提供者
2、开发
2.1 依赖
Grable
// https://mvnrepository.com/artifact/net.javacrumbs.shedlock/shedlock-spring
implementation group: 'net.javacrumbs.shedlock', name: 'shedlock-spring', version: '4.29.0'
// https://mvnrepository.com/artifact/net.javacrumbs.shedlock/shedlock-provider-redis-spring
implementation group: 'net.javacrumbs.shedlock', name: 'shedlock-provider-redis-spring', version: '4.29.0'
// https://mvnrepository.com/artifact/org.apache.commons/commons-pool2
implementation group: 'org.apache.commons', name: 'commons-pool2', version: '2.11.1'
Maven
<!-- 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-redis-spring -->
<dependency>
<groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-provider-redis-spring</artifactId>
<version>4.29.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-pool2 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.11.1</version>
</dependency>
配送Redis
spring:
# Redis相关配置
redis:
host: localhost # redis地址
password: ******* # 面膜
database: 0
port: 6379
timeout: 200
lettuce: #使用Lettuce连接池
pool:
max-idle: 100
max-wait: 1000
max-active: 20
min-idle: 10
time-between-eviction-runs: 2000 # 每两秒回收一次空闲连接
ShedLock配置类
@Configuration
@EnableScheduling
@EnableSchedulerLock(defaultLockAtMostFor = "PT30S") // 强制释放时间,当任务执行超过指定时间,将会强制结束并释放
public class ShedLockConfig {
@Value("${spring.profiles.active}")
private String env;
@Bean
public LockProvider redisLockProvider(RedisConnectionFactory factory) {
return new RedisLockProvider(factory,env); // 使用Redis管理锁
}
}
定时任务类
@Component // 定时任务是一个组件
@Slf4j
public class RstheScheduleTask {
// @SchedulerLock注解里面对于任务独占锁的时间有两个配置项:
// lockAtLeastFor:成功执行定时任务时任务节点所能拥有独占锁的最短时间;
// lockAtMostFor:成功执行定时任务时任务节点所能拥有独占锁的最长时间;
@Scheduled(cron = "*/5 * * * * ?") // 每15秒执行一次
@SchedulerLock(name = "rsthe",lockAtLeastFor = "PT10S",lockAtMostFor = "PT15S")
public void runJobB() throws InterruptedException {
log.info("【CRON】定时调度任务,{}",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()));
TimeUnit.SECONDS.sleep(10); // 休眠五秒
}
}
执行结果
2021-10-23 21:05:30.009 INFO [] 22716 --- [pool-2-thread-1] com.rsthe.web.task.RstheScheduleTask : 【CRON】定时调度任务,2021-10-23 21:05:30.009
2021-10-23 21:05:45.008 INFO [] 22716 --- [pool-2-thread-1] com.rsthe.web.task.RstheScheduleTask : 【CRON】定时调度任务,2021-10-23 21:05:45.008
2021-10-23 21:06:00.012 INFO [] 22716 --- [pool-2-thread-2] com.rsthe.web.task.RstheScheduleTask : 【CRON】定时调度任务,2021-10-23 21:06:00.012
Redis中的内容