工作小结-ShedLock的使用
ShedLock简介
ShedLock 保证任务最多同时执行一次,当一个节点获取到任务并开始执行,那么其他节点不会等待,而是直接跳过。
它不是一个分布式调度程序,更像是一个分布式锁,在分布式锁的基础上对调度任务做了扩展,使得分布式服务下的定时任务看起来像分布式调度任务一样。
此外,ShedLock 的锁是基于时间的,并且 ShedLock 在乐观上是假设所有节点上的时钟是同步的。
ShedLock 的Github地址:https://github.com/lukas-krecan/ShedLock
ShedLock组成
ShedLock 分为三部分:
- Core 核心:提供锁机制。
- Integration 集成:使用 Spring AOP、Micronaut AOP 或手写代码与业务项目代码集成。
- Lock Provider 锁提供程序:使用 SQL 数据库、Mongo、Redis 等外部进程提供锁。
ShedLock用法
ShedLock 基于 Spring 实现时,由于 Spring 6 的JDK依赖因素,所以 ShedLock 的5.x版本需要 JDK > 17 ,否则需要使用 ShedLock 4.x 版本。
接下来,以 Spring 项目(并非Spring Boot项目)为例,JDK 版本为 17 ,Spring 版本为 6.1.1 。
示例项目代码地址:https://github.com/wangfarui/work-report/tree/main/shedlock-schedule
启用并配置 Scheduled locking
首先需要添加 ShedLock 依赖。
1 | <dependency> |
然后,shedlock-provider-redis-spring
中依赖于 spring-data-redis
,其中 redis 的驱动器是可选的,默认有 jedis 和 lettuce 两种。示例项目使用 jedis,所以还需要添加 jedis 的依赖。
1 | <dependency> |
接下来,开始配置 ShedLock 。第一步注入LockProvider
:
1 |
|
通过上诉代码可以发现,LockProvider
基于 Redis 的实现类 RedisLockProvider
在实例化时还需要一个 RedisConnectionFactory
对象。第二步需要注入 jedis 的 ConnectionFactory:
1 |
|
配置完 ShedLock 的 LockProvider
之后,在配置类上标记 @EnableSchedulerLock
以启用 @SchedulerLock
注解的锁功能,标记@EnableScheduling
以启用@Scheduled
注解的调度功能。
1 |
|
配置定时任务
通过 @Scheduled
标记Bean对象下的方法为一个定时任务,再通过 @SchedulerLock
使得该任务在分布式服务下同时最多执行一次。
1 | @Scheduled(cron = "0/5 * * * * *") |
ShedLock总结
使用 ShedLock 大致分为三步:
- 提供一个
LockProvider
。 - 标记
@EnableSchedulerLock
注解以启用@SchedulerLock
的注解功能。 - 标记
@SchedulerLock
注解以启用锁功能。
以上操作步骤都是按照 ShedLock 默认配置来进行的,如果需要启用高级用法,例如希望@SchedulerLock
注解只作用于@Scheduled
注解下,可以指定@EnableSchedulerLock
注解的 interceptMode()
属性为 InterceptMode.PROXY_SCHEDULER 。