定时任务调度Quartz/1.理论知识
Quartz支持分布式、集群部署,且具有丰富的调度方式。
![]() |
Scheduler可看成是一个定时任务调度容器,里面可注入多组任务(JobDetail与Trigger), 而每个JobDetail又绑定了一个Job实例。一个JobDetail可对应多个Trigger,一个Trigger只能对应一个JobDetail。 |
Quartz核心元素
・Job:是Quartz中的一个函数式接口,其中的execute方法就是我们需要具体实现的业务任务逻辑。JobExecutionContext 中提供了调度上下文的各种信息。
Job 中的任务有可能并发执行,须要通过数据库锁去避免一个数据被多次处理。可以在 execute()方法上添加 @DisallowConcurrentExecution 注解解决这个问题。
・JobDetail:定义任务详情;将 job 注册到 scheduler 时,由客户端程序创建的,它包含 job 的各种属性设置,以及用于存储 job 实例状态信息的 JobDataMap。各种属性,例如:
- name 任务名称
- group 任务组
- description 任务描述
- jobClass 任务类
- jobDataMap 任务自定义参数
>JobDetail 由 JobBuilder 创建/定义,Quartz 不存储 Job 的实际实例,但是允许通过使用 JobDetail 定义一个实例。
>Job 有一个与其关联的名称和组,应该在单个 Scheduler 中唯一标识它们。
>一个 Trigger(触发器) 只能对应一个 Job(任务),但是一个 Job 可以对应多个 Trigger。JobDetal 与 Trigger 一对多
・Trigger:触发器,用于定义Job的触发条件,触发时间、执行间隔、执行频率,终止时间等;并触发Job的执行。
主要有四种类型的Trigger:SimpleTrigger、CronTrigger、DataIntervalTrigger和NthIncludedTrigger。
- SimpleTrigger:简单触发器,设置Job(任务)每隔多长时间,执行多少次。
- CronTrigger:Cron触发器,通过Cron表达式来控制任务的执行时间
- DataIntervalTrigger:日期触发器,在指定的某个时间段内,以一定的时间间隔执行任务。
- NthIncludedTrigger:日历触发器,根据一个给定的日历时间进行重复
※一个Trigger只能绑定一个Job。但是一个Job可以被多个Trigger绑定。
・Scheduler:调度器,启动Tirigger去执行Job
提供了DirectSchedulerFactory和StdSchedulerFactory等工厂类,用于支持Scheduler相关对象的产生
Scheduler 主要有三种:RemoteMBeanScheduler, RemoteScheduler 和 StdScheduler。
・JobBuilder:用于定义/构建 JobDetail 实例,用于定义作业的实例。
scheduler 的核心流程
![]() |
Scheduler 用来对 Trigger 和 Job 进行管理,Trigger 和 JobDetail 可以注册到 Scheduler 中,两者在 Scheduler 中都拥有自己的唯一的组(group)和名称(name)用来进行彼此的区分,Scheduler 可以通过任务组和名称来对 Trigger 和 JobDetail 进行管理。 |
| 每个 Scheduler 都有一个 SchedulerContext,用来保存 Scheduler 的上下文数据,Job 和 Trigger 都可以获取其中的信息。 | |
| Scheduler 是由 SchedulerFactory 创建,它有两个实现:DirectSchedulerFactory 、StdSchdulerFactory ,前者可以用来在代码里定制 Schduler 参数,后者直接读取 classpath 下的 quartz.properties(不存在就都使用默认值)配置来实例化 Scheduler。 |
Quartz核心配置文件
Quartz默认加载工程目录下的quartz.properties,如果工程目录下没有,就会去加载quartz.jar包下面的quartz.properties文件,也可自定义配置位置。配置属性大体可分为:
- 调度器属性
- 线程池属性
- 作业存储设置
- 插件配置
Misfire过失策略:针对CronTrigger和SimpleTrigger过失策略分别如下
| CronTrigger | withMisfireHandlingInstructionDoNothing | 不触发立即执行 | 等待下次Cron触发频率到达时刻开始按照Cron频率依次执行 |
| withMisfireHandlingInstructionIgnoreMisfires | 以错过的第一个频率时间立刻开始执行 |
重做错过的所有频率周期后 当下一次触发频率发生时间大于当前时间后,再按照正常的Cron频率依次执行 |
|
| withMisfireHandlingInstructionFireAndProceed | 以当前时间为触发频率立刻触发一次执行 | 然后按照Cron频率依次执行 | |
| SimpleTrigger | withMisfireHandlingInstructionFireNow | 以当前时间为触发频率立即触发执行 |
执行至FinalTIme的剩余周期次数 以调度或恢复调度的时刻为基准的周期频率,FinalTime根据剩余次数和当前时间计算得到 调整后的FinalTime会略大于根据starttime计算的到的FinalTime值 |
| withMisfireHandlingInstructionIgnoreMisfires | |||
| withMisfireHandlingInstructionNextWithExistingCount | |||
| withMisfireHandlingInstructionNowWithExistingCount | |||
| withMisfireHandlingInstructionNextWithRemainingCount | |||
| withMisfireHandlingInstructionNowWithRemainingCount | |||
核心策略枚举说明
MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY
MISFIRE_INSTRUCTION_FIRE_NOW
MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT
MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT
MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT
MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT
默认策略
CronTrigger和SimpleTrigger默认采用MISFIRE_INSTRUCTION_SMART_POLICY(基本策略是,如果是只执行一次的调度,使用MISFIRE_INSTRUCTION_FIRE_NOW使用MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT否则,使用MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT)
Quartz启动流程
以Quartz和spring整合为例,当spring容器启动时,就会装载相关的bean。
Quartz持久化
即将trigger和job基于jdbc存入数据库。有两种存储方式:RAMJobStore(将trigger和job存储在内存中),JobStoreSupport(基于jdbc将trigger和job存储到数据库中)。
RAMJobStore的存取速度非常快,但是由于其在系统被停止后所有的数据都会丢失,所以在集群应用中,必须使用JobStoreSupport。
JDBC-JobStore
将schedule相关信息保存在RDB中,有两种实现:JobStoreTX和JobStoreCMT
前者为application自己管理事务;
后者为application server管理事务,即全局JTA;
Quartz集群
Quartz集群是基于数据库实现,主要利用了数据库的悲观锁机制。一个Quartz集群中的每个节点是一个独立的Quartz应用,它又管理着其他的节点。这就意味着你必须对每个节点分别启动或停止。
Quartz集群中,独立的Quartz节点并不与另一其的节点或是管理节点通信,而是通过相同的数据库表来感知到另一Quartz应用的。
Quartz监听的种类
・JobListener:任务监听
・TriggerListener:触发器监听
・SchedulerListener:调度器监听
以监听器的种类来说,比较有价值的便是
- org.quartz.TriggerListener#triggerMisfired:错过触发时间,就可以发送邮件报警。
- org.quartz.JobListener#jobWasExecuted:当定时任务中抛出异常后,该方法可以获取到该异常信息,然后进行报警出来
Quartz比@scheduled的优点:
・Quart的定时任务可以随时修改。
・服务重启之后Quartz的任务会自动拉起来,自动在调度系统里面根据触发器设置的时间执行。
・Quartz支持集群(多台服务器部署了quartz任务,只有有一台服务器执行。而且一台服务器挂了相应的会转到其他服务器执行)。
【参考】
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐





所有评论(0)