Quartz管中窥豹之其他特性初识

in Java with 0 comment

由先前的文章,我们已经验证了Quartz到集群模式、触发器优先级、任务错过触发处理和任务有状态与并发等场景特性。

删除正运行任务

测试结果

任务删除将删除还未触发的任务及触发器信息。但不会强行中断已经触发运行的任务。

测试步骤

1、定义一个任务为休眠10秒。

waitingremovingjob_10s

2、测试用例中,任务每2秒触发。等待6秒后删除任务。

testRemoveRuningJob

查看结果,加入任务后,数据库保存了任务信息。

quartz_jobdetail_test_result

由于任务每2秒触发,而6秒后删除任务,共触发了4次,即6秒后删除任务,没有新的触发任务。删除任务也不会强行中断正在触发的任务。

testRemoveRuningJob_test_result

最后,数据库任务信息也删除了。

quartz_jobdetail_test_result_delete

代码参见

调度器根据JobKey删除任务及其相关触发器,并通知调度线程

org.quartz.core.QuartzScheduler.deleteJob(JobKey)

quartz_deletejob

集群下调度实例ID生成

测试结果

集群模式下,调度实例ID可配置自动生成,生成方式为:当前主机名 + 当前时间毫秒数

测试步骤

1、配置文件将调度实例ID设为AUTO,并加入集群

org.quartz.scheduler.instanceId: AUTO
org.quartz.jobStore.isClustered=true

2、跟踪调度工厂org.quartz.impl.StdSchedulerFactory加载配置启动过程

stdschedulerfactory_init_scheId

3、实例ID生成器org.quartz.spi.InstanceIdGenerator.generateInstanceId()生成ID

InstanceIdGenerator.generateInstanceId

可以看出默认生成器ID生成规则:HOSTNAME + CURRENT_TIME

SIMPLEGENERATOR_HOSTNAME_CURRENT_TIME

打印日志可以看出实例ID

print_scheduler_id

配置文件可以设置org.quartz.scheduler.instanceIdGenerator.class属性,指向自定义的ID生成器,自行实现ID生成算法。

优雅关机

测试结果

手动关闭Quartz调度,即调用Shutdown方法时,会停止正在运行的触发器和清除所有调度相关的资源。关闭调度线程、关闭错过触发线程、关闭集群管理线程、关闭连接池、关闭线程池,设为True时,关闭时会等待到所有任务线程执行结束。

测试步骤

定义一个任务休眠20s,任务触发后等待15s,关闭调度。发现调度关闭会等待正在执行的任务直到任务线程结束。

quartz_shutdown_smartly

发现触发器还是持久化到数据库。

image.png

代码参见

调度器关闭方法,关闭线程、关闭触发器、关闭连接池、关闭线程池等等

org.quartz.core.QuartzScheduler.shutdown(boolean)

QuartzScheduler.shutdown

设计模式

quartz内部也应用了一些设计模式,贴下代码吧

工厂模式

quartz采用了工厂方法。调度工厂SchedulerFactory的实现类有两个标准调度工厂StdSchedulerFactory和直接调度工厂DirectSchedulerFactory,StdSchedulerFactory可通过quartz配置文件初始化调度器Scheduler,而DirectSchedulerFactory可通过创建调度器方法来获取不同类型调度器。

interface_SchedulerFactory

任务运行壳工厂JobRunShellFactory,主要有两种实现类,创建有JTA事务和没有事务的JobRunShell。JTAJobRunShellFactory会负责创建含有JTA事务的JTAJobRunShell线程,用来反射执行真正的Job任务,并包裹了一层JTA事务;而StdJobRunShellFactory负责创建简单的JobRunShell,不处理事务相关的东西

interface_JobRunShellFactory

建造者模式

Quartz提供了不同触发器类型的触发器建造者,建造者支持属性设值的链式写法

scheduleBuilder

触发器建造者,可以创建不同触发器类型的触发器

triggerBuilder

org.quartz.JobBuilder 任务建造者,负责创建JobDetail实例

org.quartz.DateBuilder 日期建造者,负责创建与任务相关的具体日期

观察者模式

org.quartz.JobListener 任务监听器,任务执行会通知改监听器

org.quartz.TriggerListener 触发器执行会通知触发器监听器

org.quartz.SchedulerListener 调度器监听器,调度器启动和关闭等动态变化、触发器动态变化、任务动态变化会通知调度器监听器

org.quartz.ListenerManager 监听器管理类,对任务监听器、触发器监听器和调度器监听器管理

QuartzScheduler任务调度后,会负责通知监听器

quartz_notify

单例模式

DirectSchedulerFactory.getInstance()

验证了删除正在运行任务,集群模式下调度实例ID生成和优雅关机等场景,和贴了quartz应用到的一些设计模式。quartz作为一款比较成熟的定时调度开源框架,受到广泛的应用和扩展不是没有道理的。