IT@程序员猿媛

Quartz 相关整理

2019-07-02  本文已影响2人  58bc06151329

文前说明

作为码农中的一员,需要不断的学习,我工作之余将一些分析总结和学习笔记写成博客与大家一起交流,也希望采用这种方式记录自己的学习之旅。

本文仅供学习交流使用,侵权必删。
不用于商业目的,转载请注明出处。

1. 概述

Quartz 特点

Quartz 的三个核心概念

引入 Quartz 的依赖

<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.3.0</version>
</dependency>

编写一个 Quartz 任务案例

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import java.text.SimpleDateFormat;
import java.util.Date;
public class HelloJob implements Job {
  public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        Date date = new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("现在的时间是:"+ sf.format(date));
        //具体的业务逻辑
        System.out.println("Hello Quartz");
    }
}
public class HelloScheduler {
    public static void main(String[] args) throws SchedulerException {
        //创建一个jobDetail的实例,将该实例与HelloJob Class绑定
        JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("myJob").build();
        //创建一个Trigger触发器的实例,定义该job立即执行,并且每2秒执行一次,一直执行
        SimpleTrigger trigger = TriggerBuilder.newTrigger().withIdentity("myTrigger").startNow().withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(2).repeatForever()).build();
        //创建schedule实例
        StdSchedulerFactory factory = new StdSchedulerFactory();
        Scheduler scheduler = factory.getScheduler();
        scheduler.start();
        scheduler.scheduleJob(jobDetail,trigger);

    }
}

Quartz 中的设计模式

2. 核心类和关系

2.1 任务

Job 作业

public interface Job {
    public void execute(JobExecutionContext context) throws JobExecutionException;
}

JobDetail 作业详情

JobDetail jobDetail = new JobDetail("myJob",             // job name
                                    sched.DEFAULT_GROUP, // job group
                                    TestJob.class);      // job
属性 说明
JobKey 标识 Job 实例,包含 name 和 group 属性,name 为任务名称。group 为任务所在组,不设定默认为 default。
jobClass Job 接口的实现类。
jobDataMap Job 需要的参数数据。
description Job 描述。
durability 是否持久化。如果 Job 设置为非持久,当没有活跃的 trigger 与之关联的时候,Job 会自动从 scheduler 中删除。非持久 Job 的生命期是由 trigger 的存在与否决定。JobBuilder 中的属性。
shouldRecover 是否可恢复。如果 Job 设置为可恢复,一旦 Job 执行时 scheduler 发生 hard shutdown(比如进程崩溃或关机),当 scheduler 重启后,该 Job 会被重新执行。JobBuilder 中的属性。可以通过 JobExecutionContext.isRecovering() 查询任务是否是被恢复的。

JobBuilder

JobDateMap

Job 并发

public class DoNothingJob implements Job {
    @DisallowConcurrentExecution
    public void execute(JobExecutionContext context) throws JobExecutionException {
        System.out.println("do nothing");
    }
}

JobExecutionException

2.2 触发器

Trigger

通用属性 说明
JobKey 标识 Job 实例,触发器根据此,指定 Job 实例执行。包含 name 和 group 属性,name 为任务名称。group 为任务所在组,不设定默认为 default。
StartTime 触发器的时间表首次被触发的时间,值为 java.util.Date
EndTime 触发器不再被触发的时间,值同上。
description trigger 描述。
calendarName 日历名称。
mayFireAgain 是否重复执行。
priority 优先级,默认为 5。当多个 trigger 同时触发 Job 时,线程池可能不够用,此时根据优先级来决定谁先触发。Priority 只会在 同时 触发 Trigger 的时候进行比较。如果 Trigger 上的 Job 需要恢复,那么恢复后会使用原始 Trigger 相同的 Priority。
misfireInstruction 错过 Job(未在指定时间执行的 Job)的处理策略,默认为 MISFIRE_INSTRUCTION_SMART_POLICY

TriggerState 触发器状态

状态 说明
NONE
NORMAL 正常状态
PAUSED 暂停状态
COMPLETE 完成
ERROR 错误
BLOCKED 堵塞

CompletedExecutionInstruction 执行完成时状态

状态 说明
NOOP
RE_EXECUTE_JOB 重复执行
SET_TRIGGER_COMPLETE 触发器执行完成
DELETE_TRIGGER 删除触发器
SET_ALL_JOB_TRIGGERS_COMPLETE 所有作业和触发器执行完成
SET_TRIGGER_ERROR 触发器执行错误
SET_ALL_JOB_TRIGGERS_ERROR 设置所有都是错误的

TriggerBuilder

Misfire(错失触发)策略

Calendar


SimpleTrigger

simpleSchedule()
        .withIntervalInHours(1) //每小时执行一次
        .repeatForever() //次数不限
        .build();

simpleSchedule()
    .withIntervalInMinutes(1) //每分钟执行一次
    .withRepeatCount(10) //次数为10次
    .build();

CalendarIntervalTrigger

calendarIntervalSchedule()
    .withIntervalInDays(1) //每天执行一次
    .build();

calendarIntervalSchedule()
    .withIntervalInWeeks(1) //每周执行一次
    .build();

DailyTimeIntervalTrigger

ailyTimeIntervalSchedule()
    .startingDailyAt(TimeOfDay.hourAndMinuteOfDay(9, 0)) //第天9:00开始
    .endingDailyAt(TimeOfDay.hourAndMinuteOfDay(16, 0)) //16:00 结束 
    .onDaysOfTheWeek(MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY) //周一至周五执行
    .withIntervalInHours(1) //每间隔1小时执行一次
    .withRepeatCount(100) //最多重复100次(实际执行100+1次)
    .build();

dailyTimeIntervalSchedule()
    .startingDailyAt(TimeOfDay.hourAndMinuteOfDay(9, 0)) //第天9:00开始
    .endingDailyAfterCount(10) //每天执行10次,这个方法实际上根据 startTimeOfDay+interval*count 算出 endTimeOfDay
    .onDaysOfTheWeek(MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY) //周一至周五执行
    .withIntervalInHours(1) //每间隔1小时执行一次
    .build();

CronTrigger

cronSchedule("0 0/2 8-17 * * ?") // 每天8:00-17:00,每隔2分钟执行一次
    .build();

cronSchedule("0 30 9 ? * MON") // 每周一,9:30执行一次
.build();

weeklyOnDayAndHourAndMinute(MONDAY,9, 30) //等同于 0 30 9 ? * MON 
    .build();

Cron 表达式

位置 时间域 允许值 特殊值
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 , - * /
表示式 说明
0 0 12 * * ? 每天 12 点运行
0 15 10 ? * * 每天 10:15 运行
0 15 10 * * ? 每天 10:15 运行
0 15 10 * * ? * 每天 10:15 运行
0 15 10 * * ? 2008 在 2008 年的每天 10:15 运行
0 * 14 * * ? 每天 14 点到 15 点之间每分钟运行一次,开始于 14:00,结束于 14:59。
0 0/5 14 * * ? 每天 14 点到 15 点每 5 分钟运行一次,开始于 14:00,结束于 14:55。
0 0/5 14,18 * * ? 每天 14 点到 15 点每 5 分钟运行一次,此外每天 18 点到 19 点每 5 钟也运行一次。
0 0-5 14 * * ? 每天 14:00 点到 14:05,每分钟运行一次。
0 10,44 14 ? 3 WED 3 月每周三的 14:10 分到 14:44,每分钟运行一次。
0 15 10 ? * MON-FRI 每周一,二,三,四,五的 10:15 分运行。
0 15 10 15 * ? 每月 15 日 10:15 分运行。
0 15 10 L * ? 每月最后一天 10:15 分运行。
0 15 10 ? * 6L 每月最后一个星期五 10:15 分运行。
0 15 10 ? * 6L 2007-2009 在 2007,2008,2009 年每个月的最后一个星期五的 10:15 分运行。
0 15 10 ? * 6#3 每月第三个星期五的 10:15 分运行。

2.3 调度器

Scheduler

SchedulerFactory schedulerFactory = new StdSchedulerFactory();
Scheduler scheduler = schedulerFactory.getScheduler();
DirectSchedulerFactory factory = DirectSchedulerFactory.getInstance();
Scheduler scheduler = factory.getScheduler();

SchedulerFactory

ScheduleBuilder

QuartzScheduler

2.4 JobStore

RAMJobStore

org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore

JDBCJobStore

# 配置使用 JobStoreTx
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
# 选择 driver 委托
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
# 配置表名称前缀
org.quartz.jobStore.tablePrefix = QRTZ_
# 配置数据源
org.quartz.jobStore.dataSource = myDS

TerracottaJobStore

org.quartz.jobStore.class = org.terracotta.quartz.TerracottaJobStore
org.quartz.jobStore.tcConfigUrl = localhost:9510

3. 配置说明

主调度程序 Scheduler 的配置

参数名 是否必须 类型 默认值
org.quartz.scheduler.instanceName N string 'QuartzScheduler'
org.quartz.scheduler.instanceId N string 'NON_CLUSTERED'
org.quartz.scheduler.instanceIdGenerator.class N string (class name) org.quartz.simpl.SimpleInstanceIdGenerator
org.quartz.scheduler.threadName N string instanceName+'_QuartzSchedulerThread'
org.quartz.scheduler.makeSchedulerThreadDaemon N boolean false
org.quartz.scheduler.threadsInheritContextClassLoaderOfInitializer N boolean false
org.quartz.scheduler.idleWaitTime N string 30000
org.quartz.scheduler.dbFailureRetryInterval N long 15000
org.quartz.scheduler.classLoadHelper.class N string (class name) org.quartz.simpl.CascadingClassLoadHelper
org.quartz.scheduler.jobFactory.class N string (class name) org.quartz.simpl.PropertySettingJobFactory
org.quartz.context.key.SOME_KEY N string none

使用 JTA 事务,可以设置事务相关的属性

参数名 是否必须 类型 默认值
org.quartz.scheduler.userTransactionURL N string (url) 'java:comp/UserTransaction'
org.quartz.scheduler.wrapJobExecutionInUserTransaction N boolean false
org.quartz.scheduler.skipUpdateCheck N boolean false
org.quartz.scheduler.batchTriggerAcquisitionMaxCount N int 1
org.quartz.scheduler.batchTriggerAcquisitionFireAheadTimeWindow N long 0

Quartz 线程池的配置

参数名 是否必须 类型 默认值
org.quartz.threadPool.class Y string (class name) null
org.quartz.threadPool.threadCount Y string -1
org.quartz.threadPool.threadPriority N int Thread.NORM_PRIORITY (5)

全局触发器的监听器配置

全局 job 的监听器配置

jobStore 的配置

数据源的配置

从一个应用服务中获取数据源配置

用例

#==============================================================
#Configure Main Scheduler Properties
#配置文件KEY说明参考:org.quartz.impl.StdSchedulerFactory
#默认配置文件名:quartz.properties,如果未放入配置,则使用org/quartz/quartz.properties
#==============================================================
#调度器实例名称,默认值:QuartzScheduler
org.quartz.scheduler.instanceName = quartzScheduler
#调度器实例编号自动生成,默认值:NON_CLUSTERED,可设置值:AUTO
org.quartz.scheduler.instanceId = AUTO

#==============================================================
#Configure ThreadPool
#==============================================================
#线程池实现类
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
#执行最大并发线程数量
org.quartz.threadPool.threadCount = 5
#线程优先级
org.quartz.threadPool.threadPriority = 5

#==============================================================
#Configure JobStore
#==============================================================
#持久化方式配置
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
#持久化方式配置数据驱动,标准数据库(如MYSQL)
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#quartz相关数据表前缀名
org.quartz.jobStore.tablePrefix = QRTZ_
#开启分布式部署
org.quartz.jobStore.isClustered = true
#分布式节点有效性检查时间间隔,单位:毫秒
org.quartz.jobStore.clusterCheckinInterval = 10000
#配置数据源
org.quartz.jobStore.dataSource = myDS

#==============================================================
#Configure DataSource
#==============================================================
org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.myDS.URL = jdbc:mysql://127.0.0.1:3306/51token2?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true
org.quartz.dataSource.myDS.user = root
org.quartz.dataSource.myDS.password = test
org.quartz.dataSource.myDS.maxConnections = 5
org.quartz.dataSource.myDS.validationQuery=select 0 from dual

参考资料

https://www.cnblogs.com/chen-lhx/p/5581129.html
https://www.cnblogs.com/sihuanian/p/5010872.html
https://blog.csdn.net/weixin_42139757/article/details/81321383
https://blog.csdn.net/u010648555/article/details/54863144
https://www.w3cschool.cn/quartz_doc/
https://www.cnblogs.com/zhanghaoliang/p/7886110.html

上一篇 下一篇

猜你喜欢

热点阅读