Quartz是什么?
Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。Jobs可以做成标准的Java组件或 EJBs。Quartz的最新版本为Quartz 2.3.0。
内部架构
在规模方面,Quartz跟大多数开源框架类似。大约有300个java类和接口,并被组织到12个包中。这可以和Apache Struts把大约325个类和接口以及组织到11个包中相比。尽管规模几乎不会用来作为衡量框架质量的一个特性,但这里的关键是quartz内含很多功能,这些功能和特性集是否成为、或者应该成为评判一个开源或非开源框架质量的因素。
调度器
Quartz框架的核心是调度器。调度器负责管理Quartz应用运行时环境。调度器不是靠自己做所有的工作,而是依赖框架内一些非常重要的部件。Quartz不仅仅是线程和线程管理。为确保可伸缩性,Quartz采用了基于多线程的架构。启动时,框架初始化一套worker线程,这套线程被调度器用来执行预定的作业。这就是Quartz怎样能并发运行多个作业的原理。Quartz依赖一套松耦合的线程池管理部件来管理线程环境。本篇文章中,我们会多次提到线程池管理,但Quartz里面的每个对象是可配置的或者是可定制的。
框架特征
监听器和插件
如今几乎下载任何开源框架,你必定会发现支持这两个概念。监听是你创建的java类,当关键事件发生时会收到框架的回调。例如,当一个作业被调度、没有调度或触发器终止和不再触发时,这些都可以通过设置来通知你的监听器。Quartz框架包含了调度器监听、作业和触发器监听。你可以配置作业和触发器监听为全局监听或者是特定于作业和触发器的监听。
一旦你的一个具体监听被调用,你就能使用这个技术来做一些你想要在监听类里面做的事情。例如,你如果想要在每次作业完成时发送一个电子邮件,你可以将这个逻辑写进作业里面,也可以写进JobListener里面。写进JobListener的方式强制使用松耦合有利于设计上做到更好。
Quartz插件是一个新的功能特性,无须修改Quartz源码便可被创建和添加进Quartz框架。他为想要扩展Quartz框架又没有时间提交改变给Quartz开发团队和等待新版本的开发人员而设计。
与其Quartz提供一个不能满足你需要的有限扩展点,还不如通过使用插件来拥有可修整的扩展点。
集群Quartz应用
Quartz应用能被集群,是水平集群还是垂直集群取决于你自己的需要。集群能够提供以下好处:
- 伸缩性
- 高可用性
- 负载均衡
Quartz可以借助关系数据库和JDBC作业存储支持集群。
Terracotta扩展quartz提供集群功能而不需要数据库支持。
相关工具
Quartz经常会用到cron表达式,可以使用国外网站cronmaker辅助生成cron表达式。
使用Quartz前的准备
1.建立一个Maven项目
2.引入quartz的依赖
使用quartz,我们仅仅需要在maven的pom文件中添加依赖即可。现在最新的一个版本2.3.0,大家可以在maven的仓库获取到最新的版本依赖。
地址:http://mvnrepository.com/artifact/org.quartz-scheduler/quartz
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.0</version>
</dependency>
编写第一个Quartz任务案例
实现每隔3秒钟打印一次Hello World
1.创建一个类 HelloJob.java,这个类是编写我们的具体要实现任务,即打印Hello World。
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class HelloJob implements Job{
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
//打印当前的执行时间 例如 2019-05-16 00:00:00
Date date = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("当前时间为:"+ sf.format(date));
System.out.println("Hello World");
}
}
2.创建一个类HelloScheduler.java,这个是具体触发任务的类。
public class HelloScheduler {
public static void main(String[] args) throws SchedulerException {
//创建一个jobDetail的实例,将该实例与HelloJob Class绑定
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("myJob").build();
//创建一个Trigger触发器的实例,定义该job立即执行,并且每3秒执行一次,一直执行
SimpleTrigger trigger = TriggerBuilder.newTrigger().withIdentity("myTrigger").startNow().withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(3).repeatForever()).build();
//创建schedule实例
StdSchedulerFactory factory = new StdSchedulerFactory();
Scheduler scheduler = factory.getScheduler();
scheduler.start();
scheduler.scheduleJob(jobDetail,trigger);
}
}
3.执行main方法,运行’HelloScheduler.main()’,可以看见打印出了当前时间和Hello World,这表明任务执行成功了。
Quartz的工作流程
1.创建调度工厂。
2.根据工厂取得调度器实例。
3.Builder模式构建子组件<Job,Trigger> 。
4.通过调度器组装子组件 调度器.组装<子组件1,子组件2…> 。
5.调度器.start()。