任务调度信息存储
在默认情况下Quartz将任务调度的运行信息保存在内存中,这种方法提供了最佳的性能,因为内存中数据访问最快。不足之处是缺乏数据的持久性,当程序路途停止或系统崩溃时,所有运行的信息都会丢失。
比如我们希望安排一个执行100次的任务,如果执行到50次时系统崩溃了,系统重启时任务的执行计数器将从0开始。在大多数实际的应用中,我们往往并不需要保存任务调度的现场数据,因为很少需要规划一个指定执行次数的任务。
对于仅执行一次的任务来说,其执行条件信息本身应该是已经持久化的业务数据(如锁定到期解锁任务,解锁的时间应该是业务数据),当执行完成后,条件信息也会相应改变。当然调度现场信息不仅仅是记录运行次数,还包括调度规则、JobDataMap中的数据等等。
如果确实需要持久化任务调度信息,Quartz允许你通过调整其属性文件,将这些信息保存到数据库中。使用数据库保存任务调度信息后,即使系统崩溃后重新启动,任务的调度信息将得到恢复。如前面所说的例子,执行50次崩溃后重新运行,计数器将从51开始计数。使用了数据库保存信息的任务称为持久化任务。
通过配置文件调整任务调度信息的保存策略
其实Quartz JAR文件的org.quartz包下就包含了一个quartz.properties属性配置文件并提供了默认设置。如果需要调整默认配置,可以在类路径下建立一个新的quartz.properties,它将自动被Quartz加载并覆盖默认的设置。
先来了解一下Quartz的默认属性配置文件:
代码清单5 quartz.properties:默认配置
①集群的配置,这里不使用集群
org.quartz.scheduler.instanceName = DefaultQuartzScheduler
org.quartz.scheduler.rmi.export = false
org.quartz.scheduler.rmi.proxy = false
org.quartz.scheduler.wrapJobExecutionInUserTransaction = false
②配置调度器的线程池
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 10
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
③配置任务调度现场数据保存机制
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
Quartz的属性配置文件主要包括三方面的信息:
1)集群信息;
2)调度器线程池;
3)任务调度现场数据的保存。
如果任务数目很大时,可以通过增大线程池的大小得到更好的性能。默认情况下,Quartz采用org.quartz.simpl.RAMJobStore保存任务的现场数据,顾名思义,信息保存在RAM内存中,我们可以通过以下设置将任务调度现场数据保存到数据库中:
代码清单6 quartz.properties:使用数据库保存任务调度现场数据
…
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.tablePrefix = QRTZ_①数据表前缀
org.quartz.jobStore.dataSource = qzDS②数据源名称
③定义数据源的具体属性
org.quartz.dataSource.qzDS.driver = oracle.jdbc.driver.OracleDriver
org.quartz.dataSource.qzDS.URL = jdbc:oracle:thin:@localhost:1521:ora9i
org.quartz.dataSource.qzDS.user = stamen
org.quartz.dataSource.qzDS.password = abc
org.quartz.dataSource.qzDS.maxConnections = 10
要将任务调度数据保存到数据库中,就必须使用org.quartz.impl.jdbcjobstore.JobStoreTX代替原来的org.quartz.simpl.RAMJobStore并提供相应的数据库配置信息。首先①处指定了Quartz数据库表的前缀,在②处定义了一个数据源,在③处具体定义这个数据源的连接信息。
你必须事先在相应的数据库中创建Quartz的数据表(共8张),在Quartz的完整发布包的docs/dbTables目录下拥有对应不同数据库的SQL脚本。
查询数据库中的运行信息
任务的现场保存对于上层的Quartz程序来说是完全透明的,我们在src目录下编写一个如代码清单6所示的quartz.properties文件后,重新运行代码清单2或代码清单3的程序,在数据库表中将可以看到对应的持久化信息。当调度程序运行过程中途停止后,任务调度的现场数据将记录在数据表中,在系统重启时就可以在此基础上继续进行任务的调度。
代码清单7 JDBCJobStoreRunner:从数据库中恢复任务的调度
package com.baobaotao.basic.quartz;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;
public class JDBCJobStoreRunner {
public static void main(String args[]) {
try {
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
Scheduler scheduler = schedulerFactory.getScheduler();
①获取调度器中所有的触发器组
String[] triggerGroups = scheduler.getTriggerGroupNames();
②重新恢复在tgroup1组中,名为trigger1_1触发器的运行
for (int i = 0; i < triggerGroups.length; i++) {
String[] triggers = scheduler.getTriggerNames(triggerGroups[i]);
for (int j = 0; j < triggers.length; j++) {
Trigger tg = scheduler.getTrigger(triggers[j],triggerGroups[i]);
if (tg instanceof SimpleTrigger
&& tg.getFullName().equals("tgroup1.trigger1_1")) {②-1:根据名称判断
②-1:恢复运行
scheduler.rescheduleJob(triggers[j], triggerGroups[i],tg);
}
}
}
scheduler.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
当代码清单2中的SimpleTriggerRunner执行到一段时间后非正常退出,我们就可以通过这个JDBCJobStoreRunner根据记录在数据库中的现场数据恢复任务的调度。Scheduler中的所有Trigger以及JobDetail的运行信息都会保存在数据库中,这里我们仅恢复tgroup1组中名称为trigger1_1的触发器,这可以通过如②-1所示的代码进行过滤,触发器的采用GROUP.TRIGGER_NAME的全名格式。通过Scheduler#rescheduleJob(String triggerName,String groupName,Trigger newTrigger)即可重新调度关联某个Trigger的任务。
下面我们来观察一下不同时期qrtz_simple_triggers表的数据:
1.运行代码清单2的SimpleTriggerRunner一小段时间后退出:
REPEAT_COUNT表示需要运行的总次数,而TIMES_TRIGGER表示已经运行的次数。
2.运行代码清单7的JDBCJobStoreRunner恢复trigger1_1的触发器,运行一段时间后退出,这时qrtz_simple_triggers中的数据如下:
首先Quartz会将原REPEAT_COUNT-TIMES_TRIGGER得到新的REPEAT_COUNT值,并记录已经运行的次数(重新从0开始计算)。
3.重新启动JDBCJobStoreRunner运行后,数据又将发生相应的变化:
4.继续运行直至完成所有剩余的次数,再次查询qrtz_simple_triggers表:
这时,该表中的记录已经变空。
值得注意的是,如果你使用JDBC保存任务调度数据时,当你运行代码清单2的SimpleTriggerRunner然后退出,当再次希望运行SimpleTriggerRunner时,系统将抛出JobDetail重名的异常:
Unable to store Job with name: 'job1_1' and group: 'jGroup1', because one already exists with this identification.
因为每次调用Scheduler#scheduleJob()时,Quartz都会将JobDetail和Trigger的信息保存到数据库中,如果数据表中已经同名的JobDetail或Trigger,异常就产生了。
本文使用quartz 1.6版本,我们发现当后台数据库使用MySql时,数据保存不成功,该错误是Quartz的一个Bug,相信会在高版本中得到修复。因为HSQLDB不支持SELECT * FROM TABLE_NAME FOR UPDATE的语法,所以不能使用HSQLDB数据库。
小结
Quartz提供了最为丰富的任务调度功能,不但可以制定周期性运行的任务调度方案,还可以让你按照日历相关的方式进行任务调度。Quartz框架的重要组件包括Job、JobDetail、Trigger、Scheduler以及辅助性的JobDataMap和SchedulerContext。
Quartz拥有一个线程池,通过线程池为任务提供执行线程,你可以通过配置文件对线程池进行参数定制。Quartz的另一个重要功能是可将任务调度信息持久化到数据库中,以便系统重启时能够恢复已经安排的任务。此外,Quartz还拥有完善的事件体系,允许你注册各种事件的监听器。
分享到:
相关推荐
### Quartz任务调度快速入门知识点详解 #### 一、Quartz框架简介 Quartz是一个功能强大的开源作业调度框架,被广泛应用于Java应用中实现任务的定时调度。Quartz通过对任务调度领域的核心问题进行高度抽象,提炼出...
### Quartz框架快速入门详解 #### 一、Quartz框架简介 Quartz是一个开源的作业调度框架,用于开发Java应用程序。它提供了强大的触发器(Trigger)机制用于关联作业(Job),同时还具备灵活的表达式用于配置定时...
Quartz 是一个开源的任务调度框架,它允许程序员在 Java 应用程序中安排复杂的作业执行。Quartz 提供了丰富的 API 和配置选项,使得开发者能够灵活地定义作业和触发器,实现定时任务的自动化管理。 Quartz 的核心...
【Quartz任务调度框架】 Quartz是一个开源的任务调度框架,非常适合初学者入门。它为Java开发者提供了一种高效且可控的方式来实现定时任务的调度。在各种企业应用中,任务调度的需求非常常见,例如定期清理系统垃圾...
Quartz 任务调度框架 Quartz 是一个功能强大且灵活的任务调度框架,广泛应用于各种企业应用中,例如定时清理系统垃圾文件、定时导入导出数据、定时发送邮件等等业务场景。Quartz 提供了高度可控的任务调度功能,...
Quartz调度任务学习(快速开发入门),帮助你快速掌握Quartz的开发,使用性较强
这个"quartz1.5.0 任务调度demo"应该包含了以上步骤的示例代码,可以帮助你快速理解并实践Quartz的使用。在实际开发中,你可以根据项目需求,利用Quartz的灵活性和强大功能,构建复杂且可靠的定时任务系统。
【Quartz任务调度框架】 Quartz是一个开源的任务调度框架,专为Java应用程序设计,用于创建、管理和执行计划任务。在企业应用中,任务调度是非常常见且重要的需求,例如定期清理系统垃圾文件、定时导入导出数据、...
这个项目包含15个入门实例,旨在帮助开发者快速理解并掌握Quartz在实际业务中的应用。Quartz 2.1.7是这些示例所使用的版本,它是一个稳定且功能丰富的版本。 一、Quartz基本概念 1. 作业(Jobs):Quartz中的核心元素...
本文将引导您快速入门 Quartz 框架,了解其基本使用方法。 首先,要开始使用 Quartz,您需要从官方网站下载对应的 JAR 包,通常为 quartz-<version>.jar。除此之外,根据您的需求,Quartz 可能还需要一些第三方库,...
Quartz是一款开源的作业调度框架,它允许开发者创建、组织和执行计划任务。这个实例是为初学者设计的,用于帮助理解Quartz的基本概念和使用方式。在MyEclipse 6.0.1环境下,你可以直接运行这个Spring整合Quartz的...
本示例“web环境下Quartz作业调度入门源代码(Jboss)”提供了一个基础的Quartz在Web应用中的实现,下面我们将详细探讨相关的知识点。 1. **Quartz简介** - Quartz是一个轻量级的作业调度框架,支持Cron表达式和复杂...
Quartz框架是一款强大的开源任务调度库,广泛应用于Java环境下的定时任务管理。要开始使用Quartz,首先需要在项目中引入必要的依赖。基础依赖是quartz-<version>.jar,这是Quartz的核心库。除此之外,根据你的需求,...
Quartz支持多种特性,如数据库集成、集群、插件系统、EJB作业、cron-like表达式等,这使得它成为一个功能丰富的任务调度解决方案。 在Quartz中,任务被称为“作业”(Job),每个作业都需要实现`org.quartz.Job`...
本篇文章将带你快速入门Quartz框架,了解如何在Spring中集成Quartz以及创建和执行Job。 首先,要使用Quartz框架,你需要在项目中引入必要的库文件。主要依赖的JAR是quartz-<version>.jar,此外,由于Quartz可能需要...
Quartz Scheduler 是一种功能丰富、开源的任务调度程序库,可以在任何 Java 程序中使用。它可以用来创建简单或者复杂的执行次数可以达成千上万的任务。任务可以是任何 Java 可以做的事情。 什么是 Quartz Scheduler...
- 从提供的文件"QuartzBeginnerExample"来看,可能包含了一个简单的Quartz.NET入门示例,帮助开发者快速理解如何创建、调度和运行任务。 - "作业调度.docx"可能包含了更详细的关于任务调度的理论知识和实践指南,...
分布式调度框架Quartz是OpenSymphony开源组织推出的一款强大的任务调度工具,专为Java平台设计。Quartz可以方便地与其他J2EE或J2SE应用结合,也可以单独使用。它支持创建复杂的工作流,能够处理从简单到成千上万个...