写点什么

Quartz 核心原理之架构及基本元素介绍 | 京东物流技术团队

  • 2023-12-05
    北京
  • 本文字数:2992 字

    阅读完需:约 10 分钟

Quartz核心原理之架构及基本元素介绍 | 京东物流技术团队

1 什么是 Quartz

Quartz 是一个作业调度框架,它可以与 J2EE 和 J2SE 应用相结合,也可以单独使用。它能够创建多个甚至数万个 jobs 这样复杂的程序,jobs 可以做成标准的 java 组件或 EJBS。Quartz 很容易上手,创建一个任务仅需实现 Job 接口,该接口只有一个方法 void execute(JobExecutionContext context) throws JobExecutionException;在 java 实现类添加作业逻辑,当配置好 Job 实现类并设置调度时间表后,Quartz 将会监控任务的剩余时间,当调度程序确定需要通知需要执行该任务的时候,Quartz 将会调用 Job 实现类的 execute 方法执行任务。

2 系统设计

Quartz 框架的原理主要是通过将 Job 注册到调度器,再通过触发器策略执行 Job,系统设计如下:


3 核心元素介绍

Quartz 框架的核心是调度器 scheduler,核心的组件包括 Job(任务)、JobDetail(任务描述)、Trigger(触发器)。调度器负责管理 Quartz 应用运行时环境。调度器不是靠自己做所有的工作,而是依赖框架内一些非常重要的部件。Quartz 不仅仅是线程和线程管理。为确保可伸缩性,Quartz 采用了基于多线程的架构。启动时,框架初始化一套 worker 线程,这套线程被调度器用来执行预定的作业。这就是 Quartz 怎样能并发运行多个作业的原理。Quartz 依赖一套松耦合的线程池管理部件来管理线程环境。

3.1 Job

Job 是一个接口,只有一个方法 void execute(JobExecutionContext context) throws JobExecutionException。作业类需要实现接口中的 execute 方法,JobExecutionContext 提供了调度的上下文信息,每一次执行 Job 都会重新创建一个 Job 对象实例。如下:


public interface Job {
/* * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Interface. * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/** * <p> * Called by the <code>{@link Scheduler}</code> when a <code>{@link Trigger}</code> * fires that is associated with the <code>Job</code>. * </p> * * <p> * The implementation may wish to set a * {@link JobExecutionContext#setResult(Object) result} object on the * {@link JobExecutionContext} before this method exits. The result itself * is meaningless to Quartz, but may be informative to * <code>{@link JobListener}s</code> or * <code>{@link TriggerListener}s</code> that are watching the job's * execution. * </p> * * @throws JobExecutionException * if there is an exception while executing the job. */ void execute(JobExecutionContext context) throws JobExecutionException;
}public class ClosePayJob implements Job{public void execute(JobExecutionContext context) throws JobExecutionException{//业务逻辑}}
复制代码

3.2 JobDetail

Quartz 框架在每次执行 Job 时,都会重新创建一个 Job 对象实例,所以它需要 Job 类的信息以及其他相关信息,以便能够在运行时通过 newInstance()的反射机制实例化 Job。因此需要通过一个类来描述 Job 的实现类及其它相关的静态信息,比如 Job 名字、描述、关联监听器等信息。JobDetail 接口包含了能够创建 Job 类的信息载体,用来保存任务的详细信息。如下代码定义


public interface JobDetail extends Serializable, Cloneable {
public JobKey getKey();
/** * <p> * Return the description given to the <code>Job</code> instance by its * creator (if any). * </p> * * @return null if no description was set. */ public String getDescription();
/** * <p> * Get the instance of <code>Job</code> that will be executed. * </p> */ public Class<? extends Job> getJobClass();
/** * <p> * Get the <code>JobDataMap</code> that is associated with the <code>Job</code>. * </p> */ public JobDataMap getJobDataMap();
/** * <p> * Whether or not the <code>Job</code> should remain stored after it is * orphaned (no <code>{@link Trigger}s</code> point to it). * </p> * * <p> * If not explicitly set, the default value is <code>false</code>. * </p> * * @return <code>true</code> if the Job should remain persisted after * being orphaned. */ public boolean isDurable();
/** * @see PersistJobDataAfterExecution * @return whether the associated Job class carries the {@link PersistJobDataAfterExecution} annotation. */ public boolean isPersistJobDataAfterExecution();
/** * @see DisallowConcurrentExecution * @return whether the associated Job class carries the {@link DisallowConcurrentExecution} annotation. */ public boolean isConcurrentExectionDisallowed();
/** * <p> * Instructs the <code>Scheduler</code> whether or not the <code>Job</code> * should be re-executed if a 'recovery' or 'fail-over' situation is * encountered. * </p> * * <p> * If not explicitly set, the default value is <code>false</code>. * </p> * * @see JobExecutionContext#isRecovering() */ public boolean requestsRecovery();
public Object clone();
/** * Get a {@link JobBuilder} that is configured to produce a * <code>JobDetail</code> identical to this one. */ public JobBuilder getJobBuilder();
}
复制代码

3.3 Trigger

触发器(org.quartz.Trigger)抽象类的几个主要属性和 JobDetail 差不多,这里就不说明了,主要注意的是 misfireInstruction 这个属性,misfireInstruction 这个属性的是触发器错失执行(misfire)后的一个错失触发机制标识。当线程池中没有可用的线程执行任务时,就会错过触发时间,Trigger 抽象类中默认错失触发机制是常量 0(聪明的策略)。派生类有它们自己的错失触发机制。最常用的两种是 SimpleTrigger 和 CronTrigger。

3.3.1 SimpleTrigger

指定从某一个时间开始,以一定的时间间隔(单位是毫秒)执行的任务。


它适合的任务类似于:9:00 开始,每隔 1 小时,执行一次。


它的属性有:


  • repeatInterval 重复间隔

  • repeatCount 重复次数。实际执行次数是 repeatCount+1。因为在 startTime 的时候一定会执行一次。** 下面有关 repeatCount 属性的都是同理

3.3.2 CronTrigger

适合于更复杂的任务,它支持类型于 Linux Cron 的语法(并且更强大)。基本上它覆盖了其他 Trigger 的绝大部分能力—— 当然,也更难理解。


它适合的任务类似于:每天 0:00,9:00,18:00 各执行一次。


它的属性只有:Cron 表达式。

4 总结

本次文章只是对 Quartz 的架构和基本元素做了简单的介绍,后面我们会深入分析 Quartz 的核心类。


作者:京东物流 贾永强

来源:京东云开发者社区 自猿其说 Tech 转载请注明来源

发布于: 2 小时前阅读数: 8
用户头像

拥抱技术,与开发者携手创造未来! 2018-11-20 加入

我们将持续为人工智能、大数据、云计算、物联网等相关领域的开发者,提供技术干货、行业技术内容、技术落地实践等文章内容。京东云开发者社区官方网站【https://developer.jdcloud.com/】,欢迎大家来玩

评论

发布
暂无评论
Quartz核心原理之架构及基本元素介绍 | 京东物流技术团队_Java_京东科技开发者_InfoQ写作社区