文章目录
1. 引言
XXL Job和azkaban的任务调度功能都是基于quartz来开发的,并且Spring也集成了Quartz模块。 所以如果想深入了解调度原理,那其实有必要先对Quartz做一番较深入地了解。
Quartz 的github: https://github.com/quartz-scheduler/quartz
2. Quartz概述
2.1. 可以用来做什么
Quartz是一个任务调度框架,当遇到以下问题时:
- 想在每月25号,自动还款;
- 想在每年4月1日给当年自己暗恋的女神发一封匿名贺卡;
- 想每隔1小时,备份一下自己的各种资料。
那么总结起来就是,在一个有规律的时间点做一些事情,并且这个规律可以非常复杂,复杂到了需要一个框架来帮助我们。Quartz的出现就是为了解决这个问题,定义一个触发条件,那么其负责到了特定的时间点,触发相应的job干活。
2.2. 特点
- 强大的调度功能,例如丰富多样的调度方法,可以满足各种常规和特殊需求;
- 灵活的应用方式,比如支持任务调度和任务的多种组合,支持数据的多种存储(DB,RAM等;
- 支持分布式集群,在被Terracotta收购之后,在原来基础上进行了进一步的改造。
3. quartz基本原理
3.1. 核心元素
Quartz核心要素有Scheduler、Trigger、Job、JobDetail,其中trigger和job、jobDetail为元数据,而Scheduler为实际进行调度的控制器。
-
Trigger
Trigger用于定义调度任务的时间规则,在Quartz中主要有四种类型的Trigger:SimpleTrigger、CronTrigger、DataIntervalTrigger和NthIncludedTrigger。trigger状态:WAITING,ACQUIRED,EXECUTING,COMPLETE,BLOCKED,ERROR,PAUSED,PAUSED_BLOCKED,DELETED。
-
Job&Jodetail
Quartz将任务分为Job、JobDetail两部分,其中Job用来定义任务的执行逻辑,而JobDetail用来描述Job的定义(例如Job接口的实现类以及其他相关的静态信息)。对Quartz而言,主要有两种类型的Job,StateLessJob、StateFulJob -
Scheduler
实际执行调度逻辑的控制器,Quartz提供了DirectSchedulerFactory和StdSchedulerFactory等工厂类,用于支持Scheduler相关对象的产生。
3.2. 核心元素间关系
-
scheduler由工厂类SchedulerFactory创建,主要负责job和trigger的持久化管理,包括新增、删除、修改、触发、暂停、恢复调度、停止调度等;
-
一个job可以关联多个trigger,但是一个trigger只能关联一个job。
3.3. 主要线程
负责任务调度的几个线程:
- 任务执行线程池:通常使用一个线程池(SimpleThreadPool)维护一组线程,负责实际每个job的执行。
- Scheduler调度线程QuartzSchedulerThread :轮询存储的所有 trigger,如果有需要触发的 trigger,即到达了下一次触发的时间,则从任务执行线程池获取一个空闲线程,执行与该 trigger 关联的任务。
- 处理misfire job的线程MisfireHandler:轮训所有misfire的trigger,原理就是从数据库中查询所有下次触发时间小于当前时间的trigger,按照每个trigger设定的misfire策略处理这些trigger。
3.4. 数据存储
Quartz中的trigger和job需要存储下来才能被使用。Quartz中有两种存储方式:RAMJobStore,JobStoreSupport,其中RAMJobStore是将trigger和job存储在内存中,而JobStoreSupport是基于jdbc将trigger和job存储到数据库中。RAMJobStore的存取速度非常快,但是由于其在系统被停止后所有的数据都会丢失,所以在集群应用中,必须使用JobStoreSupport。其中表结构如下表所示。
Table name | Description |
---|---|
QRTZ_CALENDARS | 存储Quartz的Calendar信息 |
QRTZ_CRON_TRIGGERS | 存储CronTrigger,包括Cron表达式和时区信息 |
QRTZ_FIRED_TRIGGERS | 存储与已触发的Trigger相关的状态信息,以及相联Job的执行信息 |
QRTZ_PAUSED_TRIGGER_GRPS | 存储已暂停的Trigger组的信息 |
QRTZ_SCHEDULER_STATE | 存储少量的有关Sc |