[TOC]
第一章 Quartz
1.1 Quartz 概念
Quartz 是 OpenSymphony 开源组织的一个 Java 开源项目, 在 2009 被 Terracotta 收购. Quartz 官网
1.2 Quartz 任务调度主要元素
Quartz 任务调度的主要元素有:
: Trigger(触发器)
: Scheduler(任务调度器)
: Job(任务)
其中 Trigger,Job 是元数据,Scheduler 才是任务调度的控制器.
1.3 Quartz 特点
强大的调度功能,例如支持多样的调度方式
灵活的应用方式,例如支持任务和调度的多种组合方式
分布式和集群功能,在被 Terracotta 收购后,在 Quartz 的基础上的拓展
1.4 Quartz 基本元素关系图
Quartz 基本元素关系图
第二章 Trigger(触发器)
2.1 Trigger 定义
Trigger 也即触发器,用于定义任务调度时间规则
2.2 Trigger 属性
startTime 和 endTime
所有的 Trigger 都包含 startTime,endTime 这两个属性
优先级 (Priority)
触发器的优先级值默认为 5,不过注意优先级是针对同一时刻来说的,在同一时刻优先级高的先触发.假如一个触发器被执行时间为 3:00,另外一个为 3:01,那么肯定是先执行时间为 3:00 的触发器.
错失触发 (Misfire) 策略
在任务调度中,并不能保证所有的触发器都会在指定时间被触发,假如 Scheduler 资源不足或者服务器重启的情况,就好发生错失触发的情况.
2.3 Trigger 类型
在任务调度 Quartz 中,Trigger 主要的触发器有:SimpleTrigger,CalendarIntervelTrigger,DailyTimeIntervalTrigger,CronTrigger,注意,本博客所介绍的触发器都是基于 Quartz2.2.x 版本的,不同版本,触发器类型略有不同.
2.3.1 SimpleTrigger
SimpleTrigger 是一种最基本的触发器,指定从某一个时间开始,以一定的时间间隔执行的任务.
SimpleTrigger 的属性有:
: repeatInterval 重复间隔
: repeatCount 重复次数,实际执行次数是 repeatCount+1.
CalendarIntervalTrigger 和 SimpleTrigger 不同的是指定的时间间隔为毫秒,CalendarIntervalTrigger 支持的间隔单位有秒,分钟,小时,天,月,年,星期.
simpleSchedule()
//.withIntervalInHours(1) //每小时执行一次
.withIntervalInMinutes(1) //每分钟执行一次
//.repeatForever() //次数不限
.withRepeatCount(10) //次数为10次
.build(); //构建
2.3.2 CalendarIntervalTrigger
CalendarIntervalTrigger 的属性有:
: interval 执行间隔
: intervalUnit 执行间隔的单位(秒,分钟,小时,天,月,年,星期)
DailyTimeIntervalTrigger 和 SimpleTrigger 不同的是不仅可以支持 SimpleTrigger 支持时间间隔类型,而且还支持指定星期.
calendarIntervalSchedule()
.withIntervalInDays(1) //每天执行一次
//.withIntervalInWeeks(1) //每周执行一次
.build();
2.3.3 DailyTimeIntervalTrigger
DailyTimeIntervalTrigger 的属性有:
: startTimeOfDay 每天开始时间
: endTimeOfDay 每天结束时间
: daysOfWeek 需要执行的星期
: interval 执行间隔
: intervalUnit 执行间隔的单位(秒,分钟,小时,天,月,年,星期)
: repeatCount 重复次数
CronTrigger 适合于更复杂的任务,它支持 Linux Cron 的语法.CronTrigger 覆盖了以上三种 Trigger 的大部分功能.
dailyTimeIntervalSchedule().startingDailyAt(TimeOfDay.hourAndMinuteOfDay(9, 0)) //第天9:00开始
.endingDailyAt(TimeOfDay.hourAndMinuteOfDay(15, 0)) //15:00 结束
.onDaysOfTheWeek(MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY) //周一至周五执行
.withIntervalInHours(1) //每间隔1小时执行一次
.withRepeatCount(100) //最多重复100次(实际执行100+1次)
.build();
2.3.4 CronTrigge
CronTrigger 的属性只有;
: Cron 表达式,Cron 表达式需要程序员自己编写,比较复杂
Cron 表达式
cronSchedule("0 0/3 9-15 * * ?") // 每天9:00-15:00,每隔3分钟执行一次
.build();
cronSchedule("0 30 9 ? * MON") // 每周一,9:30执行一次
.build();
weeklyOnDayAndHourAndMinute(MONDAY, 9, 30) //等同于 0 30 9 ? * MON
.build();
位置 时间域 允许值 特殊值
1 秒 0-59 ,- * /
2 分钟 0-59 ,- * /
3 小时 0-23 ,- * /
4 日期 1-31 ,- * ? / L W C
5 月份 1-12 ,- * /
6 星期 1-7 ,- * ? / L C #
7 年份 (可选) 1-31 ,- * /
星号 ():可用在所有字段中,表示对应时间域的每一个时刻,例如, 在分钟字段时,表示" 每分钟 ";
问号(?):该字符只在日期和星期字段中使用,它通常指定为 "无意义的值",相当于点位符;
减号 (-):表达一个范围,如在小时字段中使用 "10-12",则表示从 10 到 12 点,即 10,11,12;
逗号 (,):表达一个列表值,如在星期字段中使用 "MON,WED,FRI",则表示星期一,星期三和星期五;
斜杠 (/):x/y 表达一个等步长序列,x 为起始值,y 为增量步长值.如在分钟字段中使用 0/15,则表示为 0,15,30 和 45 秒,而 5/15 在分钟字段中表示 5,20,35,50,你也可以使用 */y,它等同于 0/y;
L:该字符只在日期和星期字段中使用,代表 "Last" 的意思,但它在两个字段中意思不同.L 在日期字段中,表示这个月份的最后一天,如一月的 31 号,非闰年二月的 28 号;如果 L 用在星期中,则表示星期六,等同于 7.但是,如果 L 出现在星期字段里,而且在前面有一个数值 X,则表示 "这个月的最后 X 天",例如,6L 表示该月的最后星期五;
W:该字符只能出现在日期字段里,是对前导日期的修饰,表示离该日期最近的工作日.例如 15W 表示离该月 15 号最近的工作日,如果该月 15 号是星期六,则匹配 14 号星期五;如果 15 日是星期日,则匹配 16 号星期一;如果 15 号是星期二,那结果就是 15 号星期二.但必须注意关联的匹配日期不能够跨月,如你指定 1W,如果 1 号是星期六,结果匹配的是 3 号星期一,而非上个月最后的那天.W 字符串只能指定单一日期,而不能指定日期范围;
LW 组合:在日期字段可以组合使用 LW,它的意思是当月的最后一个工作日;
井号 (#):该字符只能在星期字段中使用,表示当月某个工作日.如 6#3 表示当月的第三个星期五 (6 表示星期五,#3 表示当前的第三个),而 4#5 表示当月的第五个星期三,假设当月没有第五个星期三,忽略不触发;
C:该字符只在日期和星期字段中使用,代表 "Calendar" 的意思.它的意思是计划所关联的日期,如果日期没有被关联,则相当于日历中所有日期.例如 5C 在日期字段中就相当于日历 5 日以后的第一天.1C 在星期字段中相当于星期日后的第一天.
Cron 表达式对特殊字符的大小写不敏感,对代表星期的缩写英文大小写也不敏感.
第三章 Scheduler(任务调度器)
3.1Scheduler 定义
Scheduler 就是任务调度控制器,Scheduler 有两个重要组件:ThreadPool 和 JobStore.
注意:Job 和 Trigger 需要存储下来才可以被使用.
ThreadPool 就是线程池,所有的任务都会被线程池执行
JobStore 是来存储运行时信息的,包括 Trigger,Scheduler,JobDetail,业务锁等等.JobStore 实现有 RAMJob(内存实现),JobStoreTX(JDBC,事务由 Quartz 管理),JobStoreCMT(JDBC,使用容器事务),ClusteredJobStore(集群实现) 等等
注意:Job 和 Trigger 需要存储下来才可以被使用.
3.2 Schedule 种类
Schedule 有三种:
其中 StdScheduler 最常用.
: StdScheduler
: RemoteMBeanScheduler
: RemoteScheduler
3.3 Schedule 工厂
Schedule 是由 Schedule 工厂创建的,有 DirectSchedulerFactory 或者 StdSchedulerFactory,StdSchedulerFactory 使用比较多
第四章 Job(任务)
4.1 Job 定义
Job:也就是表示被调度的任务
4.2 Job 类型
Job 有两种类型:无状态的 (stateless) 和有状态的(stateful)
区别在于:对于同一个 Trigger 来说,有状态的 Job 不能异步执行,也就是说需要等上一个任务 Job 执行完成后,才可以触发下一次执行.
4.3 Job 属性
Job 的属性有两种:volatility 和 durability
volatility 表示任务是否持久化到数据库存储;
durability 表示在没有 Trigger 关联的条件下是否保留.
volatility 和 durability 都是 boolean 类型.
第五章 Quartz 线程
5.1 Quartz 线程分类
在 Quartz 中,线程分为 Scheduler 调度线程和任务执行线程.
Scheduler 调度线程主要有:执行常规调度的线程和执行 misfired trigger 的线程.
执行常规调度的线程 (Regular Scheduler Thread):轮询查询存储的所有触发器,到达触发时间,就从线程池获取一个空闲的线程,执行与触发器关联的任务.
执行错失调度的线程 (Misfire Scheduler Thread):Misfire 线程扫描所有的触发器,检查是否有 misfired 的线程,也就是没有被执行错过的线程,有的话根据 misfire 的策略分别处理.
附录:参考资料
http://www.xuxueli.com/xxl-job/#/ https://www.ibm.com/developerworks/cn/opensource/os-cn-quartz/
来源: http://www.jianshu.com/p/4038c50efa48