What is the Quartz Job Scheduling Library?
Quartz is a richly featured, open source job scheduling library that can be integrated within virtually any Java application - from the smallest stand-alone application to the largest e-commerce system. Quartz can be used to create simple or complex schedules for executing tens, hundreds, or even tens-of-thousands of jobs; jobs whose tasks are defined as standard Java components that may execute virtually anything you may program them to do. The Quartz Scheduler includes many enterprise-class features, such as support for JTA transactions and clustering.
Quartz is freely usable, licensed under the Apache 2.0 license.
Quartz Job Scheduling Library是什么? Quartz是功能强大的开源作业调度库,几乎可以集成到任何Java应用程序中-从最小的独立应用程序到最大的电子商务系统。 Quartz可用于创建简单或复杂的计划,以执行数以十计,百计,万计的工作。任务标准Java组件的任务,都可以执行您对其执行的任何编程操作。Quartz Scheduler包含许多企业级功能,例如对JTA事务和集群的支持。
Quartz是免费使用的,并根据Apache 2.0许可获得许可。
Quartz 是 OpenSymphony 开源组织在任务调度领域的一个开源项目,完全基于 Java 实现。该项目于 2009 年被 Terracotta 收购,目前是 Terracotta 旗下的一个项目。官网地址:http://www.quartz-scheduler.org/
当遇到以下问题时:
像这种某个时间点执行任务,或者每隔一段时间重复执行任务,都可以用Quartz实现
Quartz任务调度的核心元素主要有:Scheduler任务调度器、Trigger触发器、Job任务、JobDetail调度程序。其中trigger和job、jobDetail为任务调度的元数据,而Scheduler为实际执行调度的控制器。
任务调度器,一个调度容器中可以注册多个JobDetail和Trigger。当Trigger与JobDetail组合,就可以被Scheduler容器调度了。正常情况下一个应用只需要一个Scheduler对象。
Scheduler 由 SchedulerFactory 创建:DirectSchedulerFactory或者StdSchedulerFactory。第二种工厂StdSchedulerFactory使用较多,因为DirectSchedulerFactory使用起来不够方便,需要作许多详细的手工编码设置。Scheduler主要有三种:RemoteMBeanScheduler,RemoteScheduler和StdScheduler。
触发器,调度任务的时间规则。Quartz中主要提供了四种类型的Trigger:SimpleTrigger,CronTirgger,DateIntervalTrigger,和NthIncludedDayTrigger。这四种trigger可以满足企业应用中的绝大部分需求。
一些日历特定时间点的集合。一个trigger可以包含多个Calendar,以便排除或包含某些时间点。
JobDetail是一个具体的可执行的调度程序,Job是这个可执行调度程序所要执行的内容,另外JobDetail还包含了任务调度的方案和策略。
JobDetail绑定指定的Job,每次Scheduler调度执行一个Job的时候,首先会拿到对应的Job,然后创建该Job实例,再去执行Job中的execute()的内容,任务执行结束后,关联的Job对象实例会被释放,且会被JVM GC清除。
为什么设计成JobDetail + Job,不直接使用Job
JobDetail定义的是任务数据,而真正的执行逻辑是在Job中。
这是因为任务是有可能并发执行,如果Scheduler直接使用Job,就会存在对同一个Job实例并发访问的问题。而 JobDetail 绑定 Job 方式,Sheduler每次执行,都会根据JobDetail创建一个新的Job实例,这样就可以规避并发访问的问题。
任务,表示要执行的具体工作或者被调度的任务。我们的任务类实现该接口,重写execute方法来定义任务的执行逻辑。主要有两种类型的job:无状态的(stateless)和有状态的(stateful)。对于同一个trigger来说,有状态的job不能被并行执行,只有上一次触发的任务被执行完之后,才能触发下一次执行。Job主要有两种属性:volatility和durability,其中volatility表示任务是否被持久化到数据库存储,而durability表示在没有trigger关联的时候任务是否被保留。两者都是在值为true的时候任务被持久化或保留。一个job可以被多个trigger关联,但是一个trigger只能关联一个job。
JobExecutionContext中包含了Quartz运行时的环境以及Job本身的详细数据信息。
当Schedule调度执行一个Job的时候,就会将JobExecutionContext传递给该Job的execute()中,Job就可以通过JobExecutionContext对象获取信息。
在Quartz中,有两类线程,也即执行线程和调度线程,其中执行任务的线程通常用一个线程池维护。线程间关系如下图
在quartz中,Scheduler调度线程主要有两个:regular Scheduler Thread(执行常规调度)和Misfire Scheduler Thread(执行错失的任务)。其中Regular Thread 轮询Trigger,如果有将要触发的Trigger,则从任务线程池中获取一个空闲线程,然后执行与Trigger关联的job;Misfire Thraed则是扫描所有的trigger,查看是否有错失的,如果有的话,根据一定的策略进行处理。
Quartz中的trigger和job需要存储下来才能被使用。Quartz中有两种存储方式:RAMJobStore,JobStoreSupport,其中RAMJobStore是将trigger和job存储在内存中,而JobStoreSupport是基于jdbc将trigger和job存储到数据库中。RAMJobStore的存取速度非常快,但是由于其在系统被停止后所有的数据都会丢失,所以在集群应用中,必须使用JobStoreSupport。
注意:quartz集群是通过数据库表来感知其他的应用的,各个节点之间并没有直接的通信。只有使用持久的JobStore才能完成Quartz集群。
quartz的sql所在位置
1、/docs/dbTables
2、org/quartz/impl/jdbcjobstore
其中表结构
Serial Number | Table Name | Description |
---|---|---|
1 | QRTZ_CALENDARS | 存储Quartz日历信息 |
2 | QRTZ_CRON_TRIGGERS | 存放Cron类型的Trigger,包括Cron表达式和时区信息 |
3 | QRTZ_FIRED_TRIGGERS | 存储与已触发的Trigger相关的状态信息,以及相联Job的执行信息 |
4 | QRTZ_PAUSED_TRIGGER_GRPS | 存储已暂停的Trigger组的信息 |
5 | QRTZ_SCHEDULER_STATE | 存储少量的Scheduler相关的状态信息 |
6 | QRTZ_LOCKS | 存储程序的悲观锁的信息(如果使用了悲观锁) |
7 | QRTZ_JOB_DETAILS | 存储每一个已配置的JobDetail信息 |
8 | QRTZ_SIMPLE_TRIGGERS | 存储Simple类型的Trigger,包括重复次数、间隔、以及已触的次数 |
9 | QRTZ_BLOG_TRIGGERS | 以Blob类型存储的Trigger |
10 | QRTZ_TRIGGERS | 存储已配置的Trigger的基本信息 |
11 | QRTZ_TRIGGER_LISTENERS | Trigger监听器 |
12 | QRTZ_JOB_LISTENERS | Job监听器 |
注意:cron方式需要用到的4张数据表: QRTZ_TRIGGERS,QRTZ_CRON_TRIGGERS,QRTZ_FIRED_TRIGGERS,QRTZ_JOB_DETAILS。