第04篇_Quartz

第01章_Quartz快速入门

第一节 Quartz简介

1. 什么是Quartz?

Quartz是一款基于Java实现的开源的任务调度库,体系结构如下:

img

核心组件包括:

扩展:

  1. 任务调度指系统中创建了 N 个任务,每个任务都有指定的时间进行执行,而这种多任务的执行策略就是任务调度。

 

2. Quartz示例

1) 引入Quartz相关依赖

 

2) 自定义任务

默认情况下,Job是无状态的,每次都会创建新的实例,上下文中的JobDataMap也是新的。可以在Job类上加上@PersistJobDataAfterExecution注解,则会变成有状态的Job,允许将数据传递给下一个Job,如统计Job执行次数。

 

3) 创建任务调度

 

3. SpringBoot整合

1) 引入依赖

 

2) 定义Job

 

3) 手动执行

 

4) 自动执行

将 JobDetail 和 Trigger 注册为Bean,任务就会随Spring启动而自动触发执行,这对需要随程序启动而执行的作业非常有用。

 

 

4. 集群模式

集群模式可以防止单点故障,减少对业务的影响,同时可以分散单个节点的压力,提升集群整体处理能力。

Quartz基于数据库实现了集群模式,支持高可用、负载均衡(随机算法)、故障恢复等。

 

1) 添加数据库相关依赖

 

2) 添加集群配置

 

3) 创建SchedulerFactory

 

4) 注意事项

 

 

第二节 常用类详解

1. Job和JobDetail

Job是任务的顶层接口,承载具体的业务逻辑,每次调用时都会创建新的实例对象。

JobDetail是任务的调度信息,可以构建和设置Job实例。

 

2. JobExecutionContext

Job执行的上下文信息,可以访问到 Quartz 运行时的环境以及 Job 本身的明细数据。

 

3. JobDataMap

一个键为String,值为Object类型的Map,用于存储和传递数据,存在于JobDetail和Trigger等中。

在Job类中,可以通过JobExecutionContext获取设置的数据,或通过Quartz框架进行注入。

 

4. Trigger

Trigger用于指定任务触发的时机,其接口和实现类如下,我们一般使用 SimpleTriggerCronTrigger 两种。

img

 

1) SimpleTrigger

SimpleTrigger适用于在特定的日期(或时间)启动,以固定的间隔时间重复执行 n 次的Job任务。

 

2) CronTrigger

CronTrigger是基于日历的作业调度器,可以做到某个时间点执行,例如“每天的凌晨1点”、“每个工作日的12点”等。

 

 

5. Scheduler

调度器(Scheduler)负责将任务(Job)和触发器(Trigger)整合起来,基于Trigger设定的时间来执行Job。

 

1) 创建和使用

 

2) 标准调度器

quartz.properties 文件配置示例如下,更多配置可参考 StdSchedulerFactory 类代码。

 

6. Listener

监听器(Listener)用于监听特定事件的发生,以便做出对应的处理,包括任务监听器、触发器监听器、调度器监听器。

 

1) JobListener

 

2) TriggerListener

 

3) SchedulerListener

 

4) 注册Listener

 

7. JobStore

作业存储(JobStore)用于定义Quartz运行时任务的存储方式。

 

1) RAMJobStore

RAMJobStore是基于内存的存储模式,调度信息保存在内存中,性能较高,但应用程序结束或崩溃时数据将丢失。

 

2) JDBCJobStore

JDBCJobStore是基于数据库的存储模式,调度信息保存在数据库中,可以持久化保存调度信息,但是性能取决于数据库性能。

下面是使用步骤:

执行任务调度后,可以在 QRTZ_JOB_DETAILS 表查看任务明细数据。

image-20240510153401393

 

 

附录

Cron表达式简介

Cron表达式由7个子表达式组成,分别是:

字段是否必填允许值可用特殊字符
0-59, - * /
0-59, - * /
0-23, - * /
日(月中的哪几天)1-31, - * / ? L C W
1-12 或 JAN-DEC, - * /
周(周中的哪几天)1-7 或 SUN-SAT, - * / ? L C #
不填写 或 1970-2099, - * /

可用的特殊字符及含义如下:

 特殊字符含义
*可用在所有字段中,表示对应时间域的每一个时刻,如:在分钟字段时,表示“每分钟”
?该字符只在日期和星期字段中使用,它通常指定为“无意义的值”,相当于点位符
-表达一个范围,如在小时字段中使用“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字符串只能指定单一日期,而不能指定日期范围
#该字符只能在星期字段中使用,表示当月某个工作日。如6#3表示当月的第三个星期五(6表示星期五,#3表示当前的第三个),而4#5表示当月的第五个星期三,假设当月没有第五个星期三,忽略不触发

Cron表达式对特殊字符的大小写不敏感,对代表星期的缩写英文大小写也不敏感。

 

Quartz表结构