定时调度 **依赖**
<dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.2.1</version></dependency><dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz-jobs</artifactId><version>2.2.1</version></dependency>
1. 核心
Jobvoid execute(JobExecutionContext context);
JobDetail
一个具体的可执行的调度程序,Job 是这个可执行调度程序所要执行的内容,JobDetail 包含了这个任务调度的方案和策略。
JobDetail 定义的是任务数据,而真正的执行逻辑是在 Job 中,设计成 JobDetail + Job 是因为任务执行时并发造成的影响,故 Scheduler 每次执行都会根据 JobDetail 创建一个新的 Job 实例,避免了并发访问的问题。
Trigger
调度参数的配置,调度时间。trigger 共性, startTime 和 endTime 指定 Trigger 被触发的区间。Priority 优先级,作用:多个Trigger在同一时刻触发,设置优先级高的任务先执行,优先级 默认5 ,设置成负数是变为默认值,优先级取值区间为 [1-10] 。
SimpleTrigger
从某一时间开始,以一定的时间间隔执行任务,时间间隔为毫秒。
**CalendarIntervalTrigger**
时间间隔为月。
**DailyTimeIntervalTrigger**
指定每天某个时间段内,以一定时间间隔执行任务,支持指定星期。
startTimeOfDay 每天开始的时间endTimeOfDay 每天结束的时间dayOfWeak 需要执行的星期onDayOfTheWeak 一周中星期几执行interval 执行时间间隔intervalUnit 执行间隔的时间单位repeatCount 重复次数
**CronTrigger**
corn表达式定义执行时间间隔。
Scheduler
调度容器,一个调度容器中可以注册多个 JobDetail 和 Trigger ,其组合可被 Scheduler 容器调度。Scheduler 是 Quartz 核心,所有的任务都是有他来创建的。
Calendarorg.quartz.Calendar
补充 Trigger 时间,排除或加入一些特定时间点。HolidayCalendar 特定的日期,精度 天 。DailyCalendar 每日的时间段格式 / HH:MM[:SS[:mmm]],精度 毫秒 。WeeklyCalendar 每个星期的星期几,精度 天 。MontnlyCalendar 每个月的几号,精度 天 。AnnualCalendar 每年的哪天。CronCalendar corn表达式,最大精度 秒 。
1.1. JobStore
存储运行时信息,包括 Trigger Scheduler JobDetail 业务锁 等。他有多种实现:
RAMJob内存实现。JobStoreTXJDBC 事务有Quartz管理。JobStoreCMTJDBC 使用容器事务。**ClusteredJobStrore**集群实现。-
1.2. SchedulerFactory
创建 Scheduler 提供两个实现:
DirectSchedulerFactory在代码里定制 Scheduler 参数StdSchdulerFactory直接读取classpath下quartz.properties参数(不存在使用默认值)配置
通常使用 StdSchedulerFactory ,SchedulerFactory 本身支持 RMI stub,可以管理远程 Scheduler,与本地一样,可以远程提交 Job。
DirectSchedulerFactory 创建接口:
public void createScheduler(String schedulerName,String schedulerInstanceId, ThreadPool threadPool, JobStore jobStore) throw SchedulerException;
2. API
2.x 后采用 DSL ( domain-specific language / 领域特定语言),例如: newTrigger newJob代码,通过 Builder 实现。 JobDetail 和 Trigger 都有 name 和 group ,相当于 Map<String(name),String(group)> 。 group 为组织单元, Scheduler 提供了一些对整组操作的API。
3. Misfire
错失触发策略
Scheduler资源不足时,或者机器崩溃重启,该触发的事件没有触发,即为 miss fire 。
注:Misfire阀值配置在jobStore,只有超过这个值才算是MisFire,小于这个值都会被重新发送。
SimpleTrigger
继承于 Trigger ,Misfire策略包含:
Trigger.MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY=-1会在资源合适的时候重新触发所有misFire任务,并且不会影响现有的调度任务时间。SimpleTrigger.MISFIRE_INSTRUCTION_FIRE_NOW=1忽略已经misFire的任务、立即执行调度,适用于只执行一次的任务。SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT=2将 startTime 设置为当前时间,立即重新调度任务,包括 Misfire 的任务。SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT=3功能与上面的基本相同,只是忽略掉 Misfire 的任务。SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT=4在下一次调度时间点,重新开启调度任务,包括Misfire。SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT=5同上,只是忽略 Misfire 。Trigger.MISFIRE_INSTRUCTION_SMART_POLICY=0所有 Trigger 的默认值,将 Misfire 的处理逻辑交由 Quartz 去处理:- MISFIRE_INSTRUCTION_FIRE_NOW 只执行一次的调度。
- MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT 无限次的调度 repeatCount 。
- MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT 其他。
4. JobDetail && Job
定义任务
- 创建 Job 实现类,实现业务逻辑。
- 定义 JobDetail,引用这个类。
- 加入 ScheduleJob。
调度任务
// 1.
JobClass jobClass = JobDetail.getJobClass();
// 2. Job实现类必须有一个public无参的构造方法
Job jobInstance = jobClass.newInstance();
// 3. JobExecutionContext是Job运行的上下文,可以获得Trigger、Scheduler、JobDetail的信息
jobInstance.execute(JobExecutionContext context);
注:每次调度都会创建一个新的Job实例,并发时不存在对临界资源的访问问题,如果需要共享JobDataMap时,还是会存在临界资源的并发访问的问题。
5. JobDataMap
每一个JobDetail都会有一个JobDataMap.
Job方法声明一个和JobDataMap中key值相同的变量利用setter方法注入进来,对于同一个JobDetail实例,执行多个Job实例,是共享同样的JobDateMap,如果在任务中修改了里面的值对其他实例也会有影响。
Job有可能是并发执行的,有时候我们不想并发执行加入 @DisallowConcurrentExecution 解决这个问题。注解对JobDetail实例生效,如果定义两个 JobDetail,引用同一个 Job 类,是可以并发执行的。
6. JobExecutionException
Job.execute() 不允许抛出除 JobExecutionException 以外的任何异常,所有异常都要 try/catch 。
7. 其他属性
DurabilityRequestsRecovery如果一个任务不是正常退出时,机器宕机、断电、不包括抛出异常这种情况。Quartz再次启动时会重新运行这个实例。8. quartz.properties
org.quartz.scheduler.instanceName = DefaultQuartzScheduler org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool org.quartz.threadPool.threadCount = 10 org.quartz.threadPool.threadPriority = 5 org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
