任务调度服务Quartz简介与入门

Quartz框架是一个全功能、开源的任务调度服务,可以集成几乎任何的java应用程序—从小的单片机系统到大型的电子商务系统。Quartz可以执行上千上万的任务调度。Quartz调度器包含许多企业级功能,例如对JTA事务和集群的支持。(最简单的调度程序就是简单的定时器,每隔多久执行一次)可以将Quatrz就当成是普通的定时任务。只是经过Quartz封装之后,可以完成更为复杂的任务调度。如果您的应用程序有需要在特定时间执行的任务,或者您的系统有经常性需要维护的工作,那么Quartz可能是您的理想解决方案。Quartz可以做以下应用:

  1. 在应用程序中提供通知服务。
  2. 系统维护:提供一个调度程序,在每个工作日(除节假日外的所有工作日)的11:30将数据库的内容转储到XML文件中。
  3. 驱动流程工作流:当一个新订单最初下达时,在两小时内启用一个程序,检查订单的状态,并在尚未收到订单确认消息时触发警告通知,以及将订单状态更改为“等待干预”。

Quartz提供了强大的运行环境和功能,几乎可以满足在应用中所使用到的任何定时任务或者调度任务,如下为Quartz官方说明的的特征:

运行环境:

  1. Quartz 可以可以嵌入另一个独立应用程序中运行。
  2. Quartz可以在应用服务器(或servlet容器)中实例化,并参与XA事务。
  3. Quartz可以作为独立的程序运行(在它自己的Java虚拟机内),可以通过RMI使用。
  4. Quartz可以实例化为一组独立程序(具有负载平衡和故障转移功能),用于执行作业。

作业调度:

作业在给定触发器发生时调度运行。可以使用以下指令的几乎任意组合创建触发器:

  1. 在一天的某个时间(精确到毫秒)
  2. 在一周的某些天
  3. 在每月的某些天
  4. 在一年的某些天
  5. 重复执行特定的次数
  6. 重复执行到特定的日期
  7. 一直重复执行
  8. 每隔一段时间执行一次
  9. 不在记录在日历中的特定日期(如营业日)

作业由其创建者命名,并且可以放在一个已经命名的群组中。触发器也可以命名并且分组,以便在调度程序中轻松使用它们。作业可以添加到调度程序一次,但可以用多个触发器注册。在企业Java环境中,作业可以作为分布式(XA)事务的一部分执行它们的工作。

作业执行:

  1. 作业可以是实现Job接口的任何Java类,为作业所能执行的工作留下无限的可能性。
  2. 作业类实例可以由Quartz或应用程序的框架实例化,比如Spring。
  3. 当触发器触发的时候,调度器通知已存在的实现JooListListor和TriggerListener接口Java对象(侦听器可以是简单Java对象,或EJB,或JMS发布者等)。这些侦听器也会在作业执行后得到通知。
  4. 当作业完成时,它们返回一个作业完成代码(JobCompletionCode),通知调度程序成功或失败。作业完成代码还可以指示调度程序根据成功/失败代码应采取的任何操作,例如立即重新执行作业。

作业持久化:

  1. Quartz的设计包括一个Jobstore接口,可以实现该接口为作业的存储提供各种机制。
  2. 使用JDBCJobstore,所有配置为“非易失性”("non-volatile")的作业和触发器都通过JDBC存储在关系数据库中。
  3. 使用 RAMJobStore,所有作业和触发器都存储在RAM中,因此在程序执行之间不会持久存在,但这是不需要外部数据库的优点

事务:

  1. Quartz可以通过JobstoreCmt(JDBCJobstore的一个子类)参与JTA事务。
  2. Quartz可以围绕作业的执行来管理JTA事务(开始并提交它们),以便作业执行的工作在JTA事务中自动发生。

集群:

  1. 故障转移
  2. 负载均衡
  3. Quartz的内置集群功能依赖于通过JDBCJobstore实现的数据库持久化(如上所述)。
  4. Terracotta扩展了Quartz的集群功能,而无需数据库就可以支持。

监听器与插件:

  1. 应用程序可以通过实现一个或多个侦听器接口捕捉调度事件以监控或者控制作业/触发器行为
  2. Quartz附带了许多“工厂模式”的插件和监听器。
  3. 插件机制可以用于向Quartz添加功能,例如保留作业执行的历史记录,或者从文件加载作业和触发器定义。

Quartz的使用比较简单,如果是Maven项目,我们可以直接在pom.xml中引入相应的jar文件。在实例中我都是使用Maven来引入依赖文件,在运行应用程序或者打包War包的时候,可以直接将依赖打包进去:

<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.2.3</version>
</dependency>
<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz-jobs</artifactId>
    <version>2.2.3</version>
</dependency>

在导入Quartz所需要的jar包之后,我们可以创建一个简单的Quartz程序,并且运行起来了。以下代码获取调度程序的实例,启动它,然后关闭它,这个过程不需要任何的配置文件,代码如下所示:

public class QuzrtzTest {
    public static void main(String[] args) {
        try {
            // 从工厂中获取一个调度器
            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
            // 定义一个作业类,并且绑定到HelloJob类上
            JobDetail job = newJob(HelloJob.class).withIdentity("job1", "group1").build();
	    // 定义一个触发器,每隔10秒重复一次
	    Trigger trigger = newTrigger().withIdentity("trigger1", "group1").startNow()			.withSchedule(simpleSchedule().withIntervalInSeconds(10).repeatForever()).build();
	    // 告诉Quartz调度器启动我们使用我们定义的作业和触发器
	    scheduler.scheduleJob(job, trigger);
	    // 启动调度器
	    scheduler.start();
	    // 关闭调度器
	    scheduler.shutdown();
	} catch (SchedulerException se) {
			se.printStackTrace();
	}
    }
}
public class HelloJob implements Job {
    private static final Logger logger = LoggerFactory.getLogger(HelloJob.class);
    public void execute(JobExecutionContext context) throws JobExecutionException {
        logger.info("正在执行调度任务");
    }
}

在调用shutdown()之前,还需要留出一些时间来触发和执行作业-对于这样的简单示例,您可能只需要添加一个thread.sleep(60000)调用。

Quartz可以使用一个名为quartz.properties的属性文件。一开始不需要这样做,但要使用除最基本(默认)配置之外的其他配置,就必须将该配置文件放到classpath中。再次,根据我的个人情况给出一个例子。我的应用程序是使用WebLogic Workshop开发的。我将所有配置文件(包括quartz.properties)保存在应用程序根目录下的项目中。当我将所有内容打包成一个.ear文件时,配置项目被打包成一个.jar,它包含在最终的.ear中。这会自动将quartz.properties放在classpath中。

如果您正在构建一个包含Quartz的Web应用程序(即.war文件的形式),您可能需要将Quartz.properties文件放在WEB-INF/classes文件夹中,以便它能在classpath中获取到。这是最重要的一点!Quartz是一个高可配置的应用程序。配置quartz的最佳方法是编辑quartz.properties文件,并将其放在应用程序的classpath中。

在Quartz发行版中有几个示例properties文件,特别是在examples/directory下。我建议您创建自己的quartz.properties文件,而不是复制其中一个示例并删除不需要的部分。这种方法能让quartz,properties文件看着更干净,你会发现Quartz提供更多的特性。为了快速启动和运行,基本的quartz.properties如下所示:

org.quartz.scheduler.instanceName = MyScheduler
org.quartz.threadPool.threadCount = 3
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore

 

  1. org.quartz.scheduler.instanceName —— 这个调度器的名字叫做"MyScheduler"
  2. org.quartz.threadPool.threadCount —— 线程池中有3个线程,这意味着最多可以同时运行3个作业。
  3. org.quartz.jobStore.class —— Quartz的所有数据,例如作业和触发器的详细信息,都保存在内存中(而不是数据库中)。即使你有一个数据库,并且想和Quartz一起使用,我建议你先使用RamJobStore创建Quartz应用,在你学习如何使用数据库创建Quartz程序之前。

猜你喜欢

转载自blog.csdn.net/wk19920726/article/details/108829203