在工作中,定时任务一直是少不了的。我们的项目中,刚开始使用的Spring自带的定时任务。后来出现了一种情况,因为现场是多副本部署的,每个副本上面都会执行一次定时任务,这就导致了数据的不一致了。于是,领导要求进行改造,考虑到现在Quartz的普及度,以及其功能的完善性,于是准备把Quartz集成到项目中去。
因此我是带着这个目的进行了Quartz的学习。主要参考的是一些博客,比如:https://www.cnblogs.com/mengrennwpu/category/1031747.html。通过学习这位大佬的博客,对Quartz有了一个初步的掌握了。下面我写的Quartz相关的文章,都是跟这个博客差不多的,我只是为了自己更好的记住和理解,所以就当做笔记,写下这些东西。如果感兴趣的可以查看这个大佬的博客。
1、什么是Quartz
百度百科的解释:Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。Jobs可以做成标准的Java组件或 EJBs。Quartz的最新版本为Quartz 2.3.0。(快照版本已经到了2.4了)
Quartz是一个完全由java编写的开源作业调度框架。
通过这个可以简单的理解为:Quartz是Java语言开发的,给我们Java开发人员来说更加亲切啊,同时是开源的。这对于我们学习它是有很大帮助的。而且它的功能强大,可以像Spring自带的定时任务一样实现简单的任务调度,也可以在集群模式下实现复杂的任务调度。它可以把定时任务相关的数据都保存到数据库(所有的数据库都能使用)中,集群模式下,多个节点也是共用同一个数据库的。
2、Quartz下载
本次使用的版本是2.2.3,下载有两种方式,完整包或Maven依赖。
1) 完整包的下载
完整包的下载地址:quartz-2.2.3-distribution.tar.gz,完整包中包含例子、源码、依赖以及说明文档等
(2) Maven依赖的导入
官网目前提供的Maven依赖为2.2.3,mvn repository目前已支持2.3.1,版本之间的更新特性本人尚未研究。quartz的依赖至少有sl4j-api相关的jar包。
<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>
3、Quartz的核心模块
quart主要有三个核心模块:Scheduler、Job、Trigger
3.1 Job
Job就是你想要实现的任务类,每一个Job必须实现org.quartz.job接口,且只需实现接口定义的execute()方法。
3.2 Trigger
Trigger为你执行任务的触发器,比如你想每天定时3点发送一份统计邮件,Trigger将会设置3点进行执行该任务。Trigger主要包含两种SimpleTrigger和CronTrigger两种。关于二者的区别的使用场景,后续文章会进行讨论。
3.3 Scheduler
Scheduler为任务的调度器,它会将任务job及触发器Trigger整合起来,负责基于Trigger设定的时间来执行Job。
4、quartz的入门案例
需求:每隔10秒钟在控制台打印 Hello World
4.1 创建maven工程
使用IDEA创建maven工程,不使用骨架。
创建maven工程是因为只需要引入相关的坐标就好了,也可以创建普通的java工程,不过那就需要我们去刚才下载好的quartz中去找到相关的jar包放到工程中。
pom.xml加入依赖:
<dependencies>
<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>
</dependencies>
4.2 创建Job实现类
Job的实现类,就是我们工作中的一个普通java类,实现了org.quartz.Job接口,
package com.zdw.zixue.job;
import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Job实现类,任意java类实现Job接口就行了
*/
public class FirstJob implements Job {
private static Logger logger = LoggerFactory.getLogger(FirstJob.class);//日志对象
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
//具体的业务逻辑在这里实现
System.out.println("----------Hello World--------------");
}
}
4.3 创建Quartz相关的服务类
该类就是用来创建定时任务的三大模块的对象的,比如:调度容器Scheduler,JobDetail,Trigger
package com.zdw.zixue.quartz;
import com.zdw.zixue.job.FirstJob;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
/**
* 该类是Quartz的服务类,用来创建程序调度器,JobDetail,Trigger等
*/
public class QuartzServer {
//创建调度容器Scheduler
public static Scheduler createScheduler() throws SchedulerException {
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
return scheduler;
}
//创建JobDetail
public static JobDetail createJobDetail(){
JobDetail jobDetail = JobBuilder.newJob(FirstJob.class)//设置执行任务的类
.withIdentity("first_job", "first_group")//job名称与job组名称组成Scheduler中任务的唯一标识
.usingJobData("message","我是第一个job的参数")//设置参数信息
.build();//构建
return jobDetail;
}
//创建trigger
public static Trigger createTrigger(){
SimpleTrigger simpleTrigger = TriggerBuilder.newTrigger()
.withIdentity("first_triggerName", "first_triggerGroup")//trigger名称与trigger组名称组成Scheduler中任务的唯一标识
.withSchedule(SimpleScheduleBuilder.simpleSchedule()//创建简单Schedule
.withIntervalInSeconds(10)//间隔时间为10秒
.repeatForever())//一直重复
.build();//构建
return simpleTrigger;
}
}
4.4 创建测试类
package com.zdw.zixue.test;
import com.zdw.zixue.quartz.QuartzServer;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
public class FirstJobTest {
public static void main(String[] args) throws SchedulerException, InterruptedException {
JobDetail jobDetail = QuartzServer.createJobDetail();//创建任务
Trigger trigger = QuartzServer.createTrigger();//创建触发器
Scheduler scheduler = QuartzServer.createScheduler();//创建调度器
//构建调度任务
scheduler.scheduleJob(jobDetail,trigger);
System.out.println("------------------创建调度任务成功---------------");
//开启任务
scheduler.start();
//30s后关闭调度器
Thread.sleep(30000);
//Scheduler的停止方法为shutdown()方法,也可以使用有参shutdown(false),
//其中参数表示是否让当前正在进行的job正常执行完成才停止Scheduler。
scheduler.shutdown(true);
System.out.println("---------------关闭了调度器----------------");
}
}
测试结果:
---------------创建调度任务成功---------------
----------Hello World--------------
----------Hello World--------------
----------Hello World--------------
----------Hello World--------------
---------------关闭了调度器----------------
该例简单说明了quartz的基本使用方式,构建调度器使用标准工厂中的默认调度器StdSchedulerFactory.getDefaultScheduler(),Job由JobBuilder进行构建,使用简单触发器SimpleTrigger,调度器的开启直接使用scheduler.start()开启即可,关闭时,调度器shutdown()方法。