1、Timer 内部使用一个叫做 TaskQueue 的类存放定时任务,它是一个基于最小堆实现的优先级队列。TaskQueue 会按照任务距离下一次执行时间的大小将任务排序,保证在堆顶的任务最先执行。这样在需要执行任务时,每次只需要取出堆顶的任务运行即可!
ScheduledExecutorService 是一个接口,有多个实现类,比较常用的是 ScheduledThreadPoolExecutor
 
需要引入依赖spring-boot-starter-web

因为 Spring Task 是 Spring Framework 的模块,所以在我们引入 spring-boot-starter-web 依赖后,无需特别引入它。

同时,考虑到我们希望让项目启动时,不自动结束 JVM 进程,所以我们引入了 spring-boot-starter-web 依赖。

我们直接通过 Spring 提供的 @Scheduled 注解即可定义定时任务,非常方便!
本文不涉及 SpringBoot 整合 Quartz 的内容,只演示了如何使用 SpringBoot 自带的实现定时任务的方式。
@Scheduled的常见用法,包括:固定速率执行、固定延迟执行、初始延迟执行、使用 Cron 表达式执行定时任务。
@Scheduled(fixedRate = 5000) // 固定速率执行。每5秒执行一次。
@Scheduled(fixedDelay = 2000) // 固定延迟执行。距离上一次调用成功后2秒才执。
@Scheduled(initialDelay = 5000, fixedRate = 5000) 初始延迟。任务的第一次执行将延迟5秒,然后将以5秒的固定间隔执行。
@Scheduled(cron = "1-2 * * * * ? ") // 使用Cron表达式。 每分钟的1,2秒运行
自定义线程池执行 scheduled task
默认情况下,@Scheduled任务都在Spring创建的大小为1的默认线程池中执行,
如果我们需要自定义线程池执行话只需要新加一个实现SchedulingConfigurer接口的 configureTasks 的类即可,这个类需要加上 @Configuration 注解。
 
如果你想要你的代码并行执行的话,还可以通过@EnableAsync 和 @Async这两个注解实现
 
Kafka、Dubbo、ZooKeeper、Netty 、Caffeine 、Akka 中都有对时间轮的实现。
时间轮简单来说就是一个环形的队列(底层一般基于数组实现),队列中的每一个元素(时间格)都可以存放一个定时任务列表。
 
上面提到的一些定时任务的解决方案都是在单机下执行的,适用于比较简单的定时任务场景比如每天凌晨备份一次数据。
如果我们需要一些高级特性比如支持任务在分布式场景下的分片和高可用的话,我们就需要用到分布式任务调度框架了。
通常情况下,一个定时任务的执行往往涉及到下面这些角色:
  • 任务 : 首先肯定是要执行的任务,这个任务就是具体的业务逻辑比如定时发送文章。
  • 调度器 :其次是调度中心,调度中心主要负责任务管理,会分配任务给执行器。
  • 执行器 : 最后就是执行器,执行器接收调度器分派的任务并执行。
 
5、Quartz
一个很火的开源任务调度框架,完全由Java写成。Quartz 可以说是 Java 定时任务领域的老大哥或者说参考标准,其他的任务调度框架基本都是基于 Quartz 开发的,比如当当网的elastic-job就是基于quartz二次开发之后的分布式调度解决方案。
Quartz 虽然也支持分布式任务。但是,它是在数据库层面,通过数据库的锁机制做的,有非常多的弊端比如系统侵入性严重、节点负载不均衡。有点伪分布式的味道。

优缺点总结:

  • 优点: 可以与 Spring 集成,并且支持动态添加任务和集群。
  • 缺点 :分布式支持不友好,没有内置 UI 管理控制台、使用麻烦(相比于其他同类型框架来说)
 

Elastic-Job 是当当网开源的一个基于Quartz和ZooKeeper的分布式调度解决方案,由两个相互独立的子项目 Elastic-Job-Lite 和 Elastic-Job-Cloud 组成,一般我们只要使用 Elastic-Job-Lite 就好。

ElasticJob 支持任务在分布式场景下的分片和高可用、任务可视化管理等功能。

 

XXL-JOB 于 2015 年开源,是一款优秀的轻量级分布式任务调度框架,支持任务可视化管理、弹性扩容缩容、任务失败重试和告警、任务分片等功能,

 

XXL-JOB 由 调度中心 和 执行器 两大部分组成。调度中心主要负责任务管理、执行器管理以及日志管理。执行器主要是接收调度信号并处理。另外,调度中心进行任务调度时,是通过自研 RPC 来实现的。

 

 

不同于 Elastic-Job 的去中心化设计, XXL-JOB 的这种设计也被称为中心化设计(调度中心调度多个执行器执行任务)。

 

 

 

 

 

 

 

非常值得关注的一个分布式任务调度框架,分布式任务调度领域的新星。目前,已经有很多公司接入比如 OPPO、京东、中通、思科。

 

 

 

 

 

总结   这篇文章中,我主要介绍了:

 

 

  • 定时任务的相关概念 :为什么需要定时任务、定时任务中的核心角色、分布式定时任务。
  • 定时任务的技术选型 : XXL-JOB 2015 年推出,已经经过了很多年的考验。XXL-JOB 轻量级,并且使用起来非常简单。虽然存在性能瓶颈,但是,在绝大多数情况下,对于企业的基本需求来说是没有影响的。PowerJob 属于分布式任务调度领域里的新星,其稳定性还有待继续考察。ElasticJob 由于在架构设计上是基于 Zookeeper ,而 XXL-JOB 是基于数据库,性能方面的话,ElasticJob 略胜一筹。