Quartz 是 OpenSymphony 开源组织在任务调度领域的一个开源项目,彻底基于 Java 实现。该项目于 2009 年被 Terracotta 收购,目前是 Terracotta 旗下的一个项目。它是一个而安全有java辨析额的开源做业调度框架。java
1.强大的调度功能,例如支持丰富多样的调度方法,能够知足各类常规及特殊需求;数据库
2.灵活的应用方式,例如支持任务和调度的多种组合方式,支持调度数据的多种存储方式;安全
3.分布式和集群能力,Terracotta 收购后在原来功能基础上做了进一步提高;框架
4.另外,做为 Spring 默认的调度框架,Quartz 很容易与 Spring 集成实现灵活可配置的调度功能。分布式
开发企业级任务调度应用:Quartz 就是启动定时任务的框架 !! !测试
利用 Quartz 进行开发至关简单,只须要将下载开发包中的 quartz-all-1.8.4.jar 加入到 classpath 便可。根据笔者的经验,对于任务调度功能比较复杂的企业级应用来讲,最好在开发阶段将 Quartz 的源代码导入到开发环境中来。一方面能够经过阅读源码了解 Quartz 的实现机理,另外一方面能够经过扩展或修改 Quartz 的一些类来实现某些 Quartz 尚不提供的功能。ui
1.Quartz定时调度框架使用说明
1) Job任务编码
具体要执行任务的程序。好比发短信,发邮件,访问数据库,同步数据,数据的清洗,本项目中使用在宣传活动定时过时的模块。spa
2)Trigger触发器 code
a)做用:它是来执行工做任务,在什么条件下触发,什么时间执行,多久执行一次。
b)四大类型:SimpleTrigger,CronTirgger,DateIntervalTrigger, 和 NthIncludedDayTrigger。
SimpleTrigger 通常用于实现每隔必定时间执行任务,以及重复多少次,如每 2 小时执行一次,重复执行 5 次。SimpleTrigger 内部实现机制是经过计算间隔时间来计算下次的执行时间,这就致使其不适合调度定时的任务。例如咱们想天天的 1:00AM 执行任务,若是使用 SimpleTrigger 的话间隔时间就是一天。注意这里就会有一个问题,即当有 misfired 的任务而且恢复执行时,该执行时间是随机的(取决于什么时候执行 misfired 的任务,例如某天的 3:00PM)。这会致使以后天天的执行时间都会变成 3:00PM,而不是咱们原来指望的 1:00AM。
CronTirgger 相似于 LINUX 上的任务调度命令 crontab,即利用一个包含 7 个字段的表达式来表示时间调度方式。例如,"0 15 10 * * ? *" 表示天天的 10:15AM 执行任务。对于涉及到星期和月份的调度,CronTirgger 是最适合的,甚至某些状况下是惟一选择。例如,"0 10 14 ? 3 WED" 表示三月份的每一个星期三的下午 14:10PM 执行任务。读者能够在具体用到该 trigger 时再详细了解每一个字段的含义。
3)scheduler定时器
Scheduler就是用来启动Trigger去执行Job。
在 Quartz 中, Scheduler 由 scheduler 工厂建立:DirectSchedulerFactory 或者 StdSchedulerFactory。 第二种工厂 StdSchedulerFactory 使用较多,由于 DirectSchedulerFactory 使用起来不够方便,须要做许多详细的手工编码设置。 Scheduler 主要有三种:RemoteMBeanScheduler, RemoteScheduler 和 StdScheduler。
2.简单案例
【使用步骤】:
1.导入quartz和quartz-job 的jar包
2.定义job任务类,该任务类须要实现接口Job,并重写方法
3.建立定时器对象
StdSchedulerFactory.getDefaultSchedule()得到的是一个定时器Scheduler对象
4.建立一个工做(jobDetail)对象实例,设置它的名字、组(当trigger去触发job的时候,是按照名字和分组去进行触发的)
a.JobBuilder.newJob(HelloJob.class) //建立builder,(jobDetail的预准备对象)
b.经过builder调用withIdentity()去设置builder的名字和分组
c.最后经过build()方法得到一个jobDetail对象
5.定义一个触发器trigger对象,用来执行jobDetail
a.TriggerBuilder.newTrigger() //建立一个触发器trigger对象,
b.withIdentity(“trigger_1”, “group_1”) //设置触发器的名字和分组
c.startNow() //设置触发器开始执行JobDetail的起始时间,还有startAt() 在指定的时间去执行
//设置以哪一种方式执行JobDetail
[有两种方式]
一种是:SimpleScheduleBuilder 简单任务的重复执行
另外一种是:CronTrigger 按日历触发任务
//以及执行一次JobDetail的间隔时间,以及执行到何时
d.withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(5))
e.build() 最终得到一个Trigger对象
6.开启定时任务
scheduler.start();
【CronTrigger 按日历触发任务 简介】 [Cron表达式]: 由7个子表达式组成的字符串,每一个子表达式都描述了一个单独的日程细节,这些子表达式用空格分割,分别表示: 1.Seconds 秒 2.Minutes 分 3.Hours 小时 4.Day-of-Month 月中的天,可选值(1-31) 5.Month 哪个月,可选值(JAN、FEB、MAR、APR、MAY、JUN、JUL、AUG、SEP、OCT、NOV、DEC) 6.Day-of-Week 周中的天,可选值(SUN、MON、TUE、WED、THU、FRI、SAT) 7.Year 年(可选的域,无关紧要) [特殊字符] '/' 用来表示增量 '?' 用来表示没有执行的值,可是,四、6不能同时使用'?' 它们必须指定一项 不然会报错 '*' 通配符,表示全部可能的值 [Cron表达式示例]: 0 0 12 ? * WED -------表示每周三的中午12:00 0/15若是放在第一位,表示从0开始,每15分钟执行一次
【使用案例1】: [建立job类,使用SimpleSchedulerBuilder]: import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; //quartz的任务 public class HelloJob implements Job { public static int i = 0; public void execute(JobExecutionContext context) throws JobExecutionException { System.out.println("hello quartz............"+(i++)); } } [测试类]: import org.junit.Test; import org.quartz.JobBuilder; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.SimpleScheduleBuilder; import org.quartz.Trigger; import org.quartz.TriggerBuilder; import org.quartz.impl.StdSchedulerFactory; import job.HelloJob; //在测试的时候遇到一个问题,若是使用JUnit来进行测试的话,进程会死掉 public class HelloScheduler { public static void main(String[] args) throws SchedulerException { //建立一个定时器对象 Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); //定义一个工做对象 JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("job_1","group1").build(); //定义触发器 Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger_1", "group_1") .startNow().withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(5)).build(); scheduler.scheduleJob(jobDetail, trigger); //开启定时任务 scheduler.start(); } }
【使用案例2】: [建立job类,使用CronSchedulerBuilder]: import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; public class SecondJob implements Job{ public void execute(JobExecutionContext context) throws JobExecutionException { System.out.println("使用crontrigger...."); } } [建立测试类]: import org.quartz.CronScheduleBuilder; import org.quartz.JobBuilder; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.Trigger; import org.quartz.TriggerBuilder; import org.quartz.impl.StdSchedulerFactory; import job.SecondJob; public class SecondScheduler { public static void main(String[] args) throws Exception { //建立一个定时器对象 Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); //建立一个jobDetail对象 JobDetail jobDetail = JobBuilder.newJob(SecondJob.class).withIdentity("job_2", "group_2").build(); //建立一trigger Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger_2", "group_2") .startNow().withSchedule(CronScheduleBuilder.cronSchedule("0 17 1 * * ?")).build(); scheduler.scheduleJob(jobDetail,trigger); scheduler.start(); } }
经过以上案例,能够了解到quart的使用和简单入门操做。
固然,做为当前颇具生命力的开源框架,Quartz 已经获得了普遍的应用。Quartz 的强大功能和应用灵活性,在企业应用中发挥了巨大的做用。本文描述了如何应用 Quartz 开发应用程序,并对企业应用中常见的问题及解决方案进行了讨论。