[TOCM]
教程2
QuartzAPI
Quartz主要接口API是:
- Scheduler:调度器调度程序的主要API进行交互。
- Job:一个接口来实现组件,您想要执行的调度器。
- JobDetail:用于定义工作的实例。
- Trigger:一个组件定义了将执行一个给定的工作时间表。
- JobBuilder: 用于定义/构建JobDetail实例,它定义Job的实例。
- TriggerBuilder:用于定义/构建Trigger实例。
Scheduler
调度器Scheduler有生命周期(SchedulerFactory 产生实例之后),在 start() 之前不会执行任何的调度操作,在shutdown()之后也不会继续调度。可以添加删除job和trigger,也可以暂停触发器
JOb 和 Trigger
package org.quartz;
public interface Job {
public void execute(JobExecutionContext context)
throws JobExecutionException;
}
- JobExecutionContext : 上下文环境信息,包含了JobDetail等对象信息
- JobDetail:包含各种属性的设置工作,以及有一个 JobDataMap 用来存放一些状态信息
- Trigger:用于触发执行或停止执行,自带一些触发类型,如常用的SimpleTrigger;也可以有JobDataMap,因为一个Job能被多个Trigger触发,
Identities 身份
Job 和 Trigger的唯一性,JobKey和TriggerKey 可用于触发分类和维护工作
以下类容来自官网:http://www.quartz-scheduler.org/documentation/quartz-2.2.x/tutorials/tutorial-lesson-04.html
JobDetail
给scheduler的实例JobDetail,我们提供的Job会被创建JobFactory工厂在触发器触发时创建新的实例对象。所以Job中不能保存状态值。
JobDetail job = newJob(DumbJob.class)
.withIdentity("myJob", "group1") // name "myJob", group "group1"
.usingJobData("jobSays", "Hello World!")
.usingJobData("myFloatValue", 3.141f)
.build();
public class DumbJob implements Job {
public DumbJob() {
}
public void execute(JobExecutionContext context)
throws JobExecutionException
{
JobKey key = context.getJobDetail().getKey();
JobDataMap dataMap = context.getJobDetail().getJobDataMap();
String jobSays = dataMap.getString("jobSays");
float myFloatValue = dataMap.getFloat("myFloatValue");
System.err.println("Instance " + key + " of DumbJob says: " + jobSays + ", and val is: " + myFloatValue);
}
}
JobDataMap : 只是在定义JobDetail时候可以把一些参数放进这里面,在Job实例中能直接获取这些数据,但是:每次被创建的Job获取到的都是被之前定义好的数据。
Trigger
最常用的两个触发器类型:Simple Triggers 和 Cron Triggers
常见的触发器属性
使用 TriggerKey 追踪定位一个触发器,使用TriggerBuilder创建触发器时设置各个属性
1. jobKey
2. startTime 在起始时间范围类开始触发
3. endTime 在超过这个时间范围后,这个触发器不再有效。 ??? 不是特别的明白
Priority 优先级
在相同执行时间点中如果有多个Job需要执行,而没有足够的资源那么就会优先执行优先级高的Job,默认是 5
Misfire Instructions 失败指令
一般用于容灾,如服务挂掉,错过了执行实现,能为这个Job指定一个失败指令。
Calendars 日历,排除某些时间不执行
SimpleTrigger
有几个特性:
1. start-time 启动时间
2. end-time 结束时间
3. repeat count 重复次数:整型, SimpleTrigger.REPEAT_INDEFINITELY(-1)表示无限循环
4. repeat interval 重复间隔,如果太短会照成多个实例并发执行
以下例子会用到 :
1. DateBuilder : 常用的时间生成,如 下一个整点,未来5秒等
2. SimpleScheduleBuilder : 生成指定的重复属性,如:间隔5秒永远循环
指定时间执行,没有重复
SimpleTrigger trigger = (SimpleTrigger) newTrigger()
.withIdentity("trigger1", "group1")
.startAt(new Date()) // some Date
.build();
指定时间执行,重复10次,每次间隔10秒
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger3", "group1")
.startAt(new Date()) // 如果开始时间没有给出,那么就以当前时间
.withSchedule(simpleSchedule()
.withIntervalInSeconds(10)
.withRepeatCount(10)) // 注意,重复10次将总共11触发
.forJob(job) // identify job with handle to its JobDetail itself
.build();
创建未来指定时间
SimpleTrigger trigger = (SimpleTrigger) newTrigger()
.withIdentity("trigger5", "group1")
.startAt(DateBuilder.futureDate(10, DateBuilder.IntervalUnit.SECOND)) // 开始时间是未来10秒
.forJob(job)
.build();
从当前时间开始,每隔5分钟执行一次,一直循环,直到22:00:00结束
trigger = newTrigger()
.withIdentity("trigger7", "group1")
.withSchedule(simpleSchedule()
.withIntervalInMinutes(5)
.repeatForever())
.endAt(dateOf(22, 0, 0)) //失效时间,未指定开始时间则按当前时间
.build();
开始时间为下一个整点:00:00,间隔两小时执行一次,永远循环
trigger = newTrigger()
.withIdentity("trigger8") // 没有指定组,将在默认组
.startAt(evenHourDate(null)) // 获取下一个整点,如现在是0:24,获取到的时间是: 1:00:00
.withSchedule(simpleSchedule()
.withIntervalInHours(2)
.repeatForever())
.build();
scheduler.scheduleJob(trigger, job);
触发失败指令策略
SimpleTrigger 中以 MISFIRE_INSTRUCTION开头的常量,但是具体没有看明白作用是什么,英文看不懂
CronTrigger 表达式触发器
以日历作为对象描述执行时间,而不是按 simpleTrigger 那样简单的循环间隔或则指定时间,如 每周五中午,每个工作日等。但是和 simpleTrigger 一样也能指定开始时间和失效时间
由7个子表达式来描述日程安排的细节
- Seconds
- Minutes
- Hours
- Day-of-Month : 自然月中的日期
- Month
- Day-of-Week : 一周中的第几天,与Day-of-Month互斥
- Year (optional field)
比如:每周三12:00:00 : 0 0 12 ? * WED
字段 | 描述 | 说明 |
---|---|---|
Seconds | - | 0-59秒 |
Minutes | - | 0-59分 |
Hours | - | 0-23小时 |
Day-of-Month | 自然月中的日期 | 1-31日 |
Month | - | 1-12月 |
Day-of-Week | 一周中的第几天,与Day-of-Month互斥 | 1-7(1=周日) |
Year | 可选字段 | - |
通配符: 一般都能作用于所有字段,除非特殊说明
通配符 | 作用域 | 描述 |
---|---|---|
* | ALL | 每个时间点 |
/ | ALL | 指定增量,如0/15 从0分开始,每15分钟执行(0+15下一个执行点),2/15 (2 + 15 下一个执行点),注意的是:增量部分为30以下,则会进行增量,30以上就与0,30(表示:第0分钟,第30分钟执行) |
? | Day-of-Month 和 Day-of-Week | 用于指定没有具体的值,月中日和星期互斥 |
L | Day-of-Month 和 Day-of-Week | 表示该字段的最后一个值,如:每个月的最后一天,每个星期的最后一天(7),官方说 使用该符合的时候不要指定列表或则范围否则会得到混乱的时间 |
W | - | 用于指定工作日最近的一天;暂不知道使用场景和意思 |
# | - | 暂不明白意思 |
JDBC
表结构解释
表名 | 描述 | 特殊说明 |
---|---|---|
QRTZ_FIRED_TRIGGERS | 存储与已触发的 Trigger 相关的状态信息,以及相联 Job 的执行信息 | 所有正常执行的trigger都会出现在这里 |
QRTZ_PAUSED_TRIGGER_GRPS | 存储已暂停的 Trigger 组的信息 | |
QRTZ_SCHEDULER_STATE | 存储少量的有关 Scheduler 的状态信息,和别的 Scheduler实例(假如是用于一个集群中) | |
QRTZ_LOCKS | 存储程序的悲观锁的信息(假如使用了悲观锁) | |
QRTZ_SIMPLE_TRIGGERS | 存储简单的Trigger,包括重复次数,间隔,以及已触的次数 | 已经被调度器接收的会存在这里 |
QRTZ_SIMPROP_TRIGGERS; | ||
QRTZ_CRON_TRIGGERS | 存储 Cron Trigger,包括 Cron 表达式和时区信息 | |
QRTZ_BLOB_TRIGGERS | Trigger 作为 Blob 类型存储(用于 Quartz 用户用 JDBC 创建他们自己定制的 Trigger 类型,JobStore并不知道如何存储实例的时候) | |
QRTZ_TRIGGERS | 存储 Cron Trigger,包括 Cron 表达式和时区信息 | 已经被调度器接收了的trigger会存在这里,如果错过了执行时间也会是完成状态,但是不会被删除此条数据,正常执行完成的会被删除掉 |
QRTZ_JOB_DETAILS | 存储已配置的 JobDetail 的信息 | 已经被调度器接收了的jobDetail会存在这里 |
QRTZ_CALENDARS | 以 Blob 类型存储 Quartz 的 Calendar 信息 |