Springboot定时任务
技术选型
- java.util.Timer 多任务、串行、粒度小,内存化
- ScheduledExecutorService 线程池并发执行,内存化
- @Scheduled 串行(可配置为并行)轻量化,内存化
- Quartz 分布式,持久化,高可用,数据库悲观锁
- elastic-job 弹性分布式,zookeeper协调,高可用
- xxl-job 轻量级,分布式,调度中心可视化
使用
-
Timer
//schedule(TimerTask task, long delay, long period) 延迟delay执行并每隔period执行一次 new Timer().schedule(new TimerTask() { @Override public void run() { //TODO } }, 0, 2000); //schedule(TimerTask task, Date time) 定时执行 new Timer().schedule(new TimerTask() { @Override public void run() { //TODO } }, new Date(2020-10-11); //schedule(TimerTask task, long delay) 延迟delay毫秒执行 new Timer().schedule(new TimerTask() { @Override public void run() { //TODO } }, 1000);
源码
【缺点】1.高度依赖系统时间,对调度的支持基于绝对时间,对系统时间改变非常敏感
2.异常即终止
3.串行任务执行,不能异步,任务相互影响
4. 数据不能持久化,关机即终止,适合单机调用 -
Timer
使用
【优缺点】并行任务执行,互不影响
实现原理基于线程池思路,性能好,每个任务一个线程
调度逻辑不能持久化
适合单机调用 -
@Scheduled
使用
@Scheduled(fixedRate=1000, initialDelay=1000) public void doSomething() { //TODO }
分布式加锁
- redis
- db唯一
- zookeeper
- etcd@Scheduled(fixedRate = 1000, initialDelay = 1000) @Async //并行调度 public void doSomething() { //这里只做了简单处理 Boolean lock = stringRedisTemplate.opsForValue().setIfAbsent("key_lock", "YES", 1000, TimeUnit.SECONDS); if (lock == null || !lock) { return; } //TODO //注意:启动类要加上 @EnableScheduling 注解 }
[注意】这里的定时调度是串行的,要想异步有两种方法
- @Async 注解
- 实现 SchedulingConfigurer
/** * 定时任务线程池配置,有多少个定时任务就多少个线程池 */ @Configuration public class ScheduleConfig implements SchedulingConfigurer { @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { taskRegistrar.setScheduler(Executors.newScheduledThreadPool(5)); } }
-
Quartz
多种持久化方式。比如支持内存存储,数据库存储,Terracotta server 存储。
支持分布式和集群能力。
采用JDBCJobStore方式存储时,针对事务的处理方式支持全局事务(和业务服务共享同一个事务)和局部事务(quarzt 单独管理自己的事务)
基于plugin机制以及listener机制支持灵活的扩展。核心组件:
- Job 工作任务,方法void execute(JobExecutionContext context)定义运行任务
- JobDetail 工作任务实例,Quartz在每次执行Job时,都重新创建一个Job实例
- Trigger 触发器,用来描述触发Job执行的时间触发规则,主要有SimpleTrigger和CronTrigger这两个子类
- Calendar 日历,特定时间点的集合一个Trigger可以和多个Calendar关联
- Scheduler 调度器,代表一个Quartz的独立运行容器,Trigger和JobDetail可以注册到
具体使用:
https://github.com/quartz-scheduler/quartz/
参考博客:
https://www.jianshu.com/p/7d6f2cc5cf70
https://cloud.tencent.com/developer/article/1631184
https://www.cnblogs.com/barrywxx/p/Quartz.html -
Elastic-Job
Elastic-Job 由两个相互独立的子项目Elastic-Job-Lite和Elastic-Job-Cloud组成。
ElasticJob-Lite:Elastic-Job-Lite为轻量级无中心化解决方案,使用jar包提供分布式任务的协调服务
ElasticJob-Cloud:Elastic-Job-Cloud使用Mesos + Docker,提供资源治理、应用分发以及进程隔离等服务
ElasticJob-Lite ElasticJob-Cloud 无中心化 是 资源分配 不支持 作业模式 常驻 部署依赖 ZooKeeper 功能列表
-
弹性调度
- 支持任务在分布式场景下的分片和高可用
- 能够水平扩展任务的吞吐量和执行效率
- 任务处理能力随资源配备弹性伸缩
-
资源分配
- 在适合的时间将适合的资源分配给任务并使其生效
- 相同任务聚合至相同的执行器统一处理
- 动态调配追加资源至新分配的任务
-
作业治理
- 失效转移
- 错过作业重新执行
- 自诊断修复
-
作业依赖(TODO)
- 基于有向无环图(DAG)的作业间依赖
- 基于有向无环图(DAG)的作业分片间依赖
-
作业开放生态
- 可扩展的作业类型统一接口
- 丰富的作业类型库,如数据流、脚本、HTTP、文件、大数据等
- 易于对接业务作业,能够与 Spring 依赖注入无缝整合
-
可视化管控端 (https://github.com/apache/shardingsphere-elasticjob-ui)
- 作业管控端
- 作业执行历史数据追踪
- 注册中心管理
环境要求
ZooKeeper 3.6.0 及其以上版本。详情参见
Mesos 1.1.0 及其兼容版本。详情参见使用:
https://github.com/apache/shardingsphere-elasticjob
https://gitee.com/elasticjob/elastic-job
https://cloud.tencent.com/developer/article/1465039
https://www.jianshu.com/p/0dca6ebb9c5a
https://developer.aliyun.com/article/692456 -