Quartz任务调度框架
一、简介
1.介绍
Quartz是功能强大的开源作业调度库,几乎可以集成到任何Java应用程序中-从最小的独立应用程序到最大的电子商务系统。Quartz可用于创建简单或复杂的计划,以执行数以万计,数以万计的工作。任务定义为标准Java组件的作业,它们实际上可以执行您可以编写的所有内容。Quartz Scheduler包含许多企业级功能,例如对JTA事务和集群的支持。Quartz是免费使用的。
2.定时器种类
SimpleTrigger,CronTirgger,DateIntervalTrigger,NthIncludedDayTrigger和Calendar 类( org.quartz.Calendar)。
最常用的:
SimpleTrigger:用来触发只执行一次或者在给定时间触发并且触发N次且每次执行延迟一定时间的任务。
CronTrigger:按照日历触发,例如“每个周五”,每个月10号上午10.15
3.存储方式
RAMJobStore(随机存储内存)和JDBCJobStore(数据库存储)
对比
4.表关系和解释
表关系
解释
qrzt_blob_triggers | tigger作为Blob类型存储(用户trigger用户用jdbc创建他们自己定制的tigger类型,jobStore并不知道如何存储实例的时候) |
---|---|
qrzt_calendars | 以Blob类型存储Quartz的日历信息,quartz可配置一个日历来指定一个时间范围 |
qrzt_cron_triggers | 存储Corn Trigger,包括Corn表达式和时区信息 |
qrtz_fired_triggers | 存储已经触发的Trigger相关的状态信息,以及相关联Job的执行信息 |
qrtz_job_details | 存储每一个已经配置的job的详细信息 |
qrtz_locks | 存储程序的悲观锁的信息(如果使用了悲观锁) |
qrtz_paused_trigger_graps | 存储已经暂停的Trigger组的信息 |
qrtz_scheduler_state | 存储了少量的有关Scheduler的状态信息,和别的Scheduler实例(假如是用作一个集群) |
qrtz_simple_triggers | 存储简单的trigger,包括重复次数,间隔,以及触发的次数 |
qrtz_triggers | 存储已经配置的trigger信息 |
qrzt_simprop_triggers | 存储简单触发器的信息 |
5.核心类和关系
核心类
QuartzSchedulerThread :负责执行向QuartzScheduler注册的触发Trigger的工作的线程。
ThreadPool:Scheduler使用一个线程池作为任务运行的基础设施,任务通过共享线程池中的线程提供运行效率。
QuartzSchedulerResources:包含创建QuartzScheduler实例所需的所有资源(JobStore,ThreadPool等)。
SchedulerFactory :提供用于获取调度程序实例的客户端可用句柄的机制。
JobStore: 通过类实现的接口,这些类要为org.quartz.core.QuartzScheduler的使用提供一个org.quartz.Job和org.quartz.Trigger存储机制。作业和触发器的存储应该以其名称和组的组合为唯一性。QuartzScheduler :这是Quartz的核心,它是org.quartz.Scheduler接口的间接实现,包含调度org.quartz.Jobs,注册org.quartz.JobListener实例等的方法。
Scheduler :这是Quartz Scheduler的主要接口,代表一个独立运行容器。调度程序维护JobDetails和触发器的注册表。 一旦注册,调度程序负责执行作业,当他们的相关联的触发器触发(当他们的预定时间到达时)。
Trigger :具有所有触发器通用属性的基本接口,描述了job执行的时间出发规则。 - 使用TriggerBuilder实例化实际触发器。JobDetail :传递给定作业实例的详细信息属性。 JobDetails将使用JobBuilder创建/定义。
Job:要由表示要执行的“作业”的类实现的接口。只有一个方法 void execute(jobExecutionContext context)(jobExecutionContext 提供调度上下文各种信息,运行时数据保存在jobDataMap中)Job有个子接口StatefulJob ,代表有状态任务。有状态任务不可并发,前次任务没有执行完,后面任务处于阻塞。
关系
一个job可以绑定多个Trigger,但是一个Trigger只能绑定一个job
6.配置文件
quartz.properties
//调度标识名 集群中每一个实例都必须使用相同的名称 (区分特定的调度器实例)
org.quartz.scheduler.instanceName:DefaultQuartzScheduler
//ID设置为自动获取 每一个必须不同 (所有调度器实例中是唯一的)
org.quartz.scheduler.instanceId :AUTO
//数据保存方式为持久化
org.quartz.jobStore.class :org.quartz.impl.jdbcjobstore.JobStoreTX
//表的前缀
org.quartz.jobStore.tablePrefix : QRTZ_
//设置为TRUE不会出现序列化非字符串类到 BLOB 时产生的类版本问题
org.quartz.jobStore.useProperties : true
//加入集群 true 为集群 false不是集群
org.quartz.jobStore.isClustered : false
//调度实例失效的检查时间间隔
org.quartz.jobStore.clusterCheckinInterval:20000
//容许的最大作业延长时间
org.quartz.jobStore.misfireThreshold :60000
//ThreadPool 实现的类名
org.quartz.threadPool.class:org.quartz.simpl.SimpleThreadPool
//线程数量
org.quartz.threadPool.threadCount : 10
//线程优先级 org.quartz.threadPool.threadPriority : 5(threadPriority 属性的最大值是常量 java.lang.Thread.MAX_PRIORITY,等于10。最小值为常量 java.lang.Thread.MIN_PRIORITY,为1)
//自创建父线程
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true
//数据库别名 org.quartz.jobStore.dataSource : qzDS
//设置数据源
org.quartz.dataSource.qzDS.driver:com.mysql.jdbc.Driver
org.quartz.dataSource.qzDS.URL:jdbc:mysql://localhost:3306/quartz
org.quartz.dataSource.qzDS.user:root org.quartz.dataSource.qzDS.password:123456
org.quartz.dataSource.qzDS.maxConnection:10
7.JDBC插入表顺序
主要的JDBC操作类,执行sql顺序。
Simple_trigger :插入顺序qrtz_job_details —> qrtz_triggers —> qrtz_simple_triggers qrtz_fired_triggers
Cron_Trigger:插入顺序qrtz_job_details —> qrtz_triggers —> qrtz_cron_triggers qrtz_fired_triggers
二、示例
package com.hgc.zm;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import java.util.Date;
/**
* @author zm
* @version 1.0
* @date 2021/4/25 11:58
*/
@Slf4j
public class RAMQuartz {
public static void main(String[] args) throws SchedulerException {
//1.创建Scheduler的工厂
SchedulerFactory sf = new StdSchedulerFactory();
//2.从工厂中获取调度器实例
Scheduler scheduler = sf.getScheduler();
//3.创建JobDetail
JobDetail jb = JobBuilder.newJob(RAMJob.class)
.withDescription("this is a ram job") //job的描述
.withIdentity("ramJob", "ramGroup") //job 的name和group
.build();
//任务运行的时间,SimpleSchedle类型触发器有效
long time= System.currentTimeMillis() + 3*1000L; //3秒后启动任务
Date statTime = new Date(time);
//4.创建Trigger
//使用SimpleScheduleBuilder或者CronScheduleBuilder
Trigger t = TriggerBuilder.newTrigger()
.withDescription("this is a trigger")
.withIdentity("ramTrigger", "ramTriggerGroup")
//.withSchedule(SimpleScheduleBuilder.simpleSchedule())
.startAt(statTime) //默认当前时间启动
.withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?")) //2秒执行一次
.build();
//5.注册任务和定时器
scheduler.scheduleJob(jb, t);
//6.启动 调度器
scheduler.start();
log.info("启动时间 : " + new Date());
}
}
package com.hgc.zm;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
/**
* @author zm
* @version 1.0
* @date 2021/4/25 12:42
*/
public class RAMJob implements Job {
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.err.println("Say hello to Quartz " + System.currentTimeMillis());
}
}