写点什么

ShedLock: 一个轻量级的定时任务协调组件

用户头像
kk
关注
发布于: 2020 年 05 月 11 日
ShedLock:一个轻量级的定时任务协调组件

文章原文

[TOC]

参考:



定时任务通常会遇到什么问题?



如果开发的服务需要水平部署实现负载均衡,那么定时任务就会同时在多个服务实例上运行,



  • 那么一方面,可能由于定时任务的逻辑处理需要访问公共资源从而造成并发问题;

  • 另一方面,就算没有并发问题,那么一个同样的任务多个服务实例同时执行,也会造成资源的浪费。



因此需要一种机制来保证多个服务实例之间的定时任务正常、合理地执行。



ShedLock 解决了什么问题?



  • ShedLock 就是一个锁,保证多个实例在同一时间只会执行一次通过一个 shared databases 来保证,比如 redis,mysql,zk 等

  • 设计思路很简单:谁能拿到锁,谁就有资格执行



同类产品的比较



略。



Quartz



  • 比较重量级,是处理定时任务的优秀框架



xxl-job



  • 带管理页面,功能强大



使用



以 redis 为例,会存储一个分布式锁,键为:



// "job-lock:flcrawler-dev:generateRss"
job-lock:{global-name}:{schedule-name}



它的值为:



"ADDED:2020-01-06T04:29:03.280Z@{global-name}-64dd7bdc7f-jdxrh"



ttl:(lockAtLeastFor 的值)



127.0.0.1:6379> ttl "job-lock:flcrawler-dev:generateRss"
(integer) 104



配置:



@Scheduled(cron = "7 0/13 * * * ?")
@SchedulerLock(name = "generateRss", lockAtMostFor = "1h", lockAtLeastFor = "10m")
public void generateRss() {
......
}



记一次遇到的 ShedLock 的一个 Bug



问题描述:





compile group: 'net.javacrumbs.shedlock', name: 'shedlock-provider-redis-spring', version: '0.18.2'



解决方案



  • 先手动删 lock,临时执行

  • shedlock-provider-redis-spring 升级到 3.0.0(2.1.0 就已经解决了)



复盘





源码:shedlock-provider-redis-spring-v0.18.2





不过另外一个provider:shedlock-provider-jedis v0.11.0一开始就规避了这个问题:





源码分析



总体脉络



ShedLock 的源码相对简单,项目分层比较清晰,比较容易理解。





  • shedlock-core 包:抽象出了默认的接口、方法、SchedulerLock 注解,不过具体的实现在 provieders 里

  • providers 包:定义了不同的 shared databases 的实现:jdbcredisetc.

  • 测试框架:mockito



各 provider 的实现



redis:



提供了一个有过期时间的分布式锁

jdbc:MariaDB、PostgreSQL、MySQL等等



创建一个用于存储 lock 的表,并插入一条关于锁的数据。



着重看一下 spring 的依赖: https://juejin.im/post/5eb166bc5188250bdf5c1ec6?utm_source=gold_browser_extension



发布于: 2020 年 05 月 11 日阅读数: 158
用户头像

kk

关注

To stay informed about the world... 2018.03.29 加入

还未添加个人简介

评论

发布
暂无评论
ShedLock:一个轻量级的定时任务协调组件