【quartz】集群运行与相关表介绍

qrtz_blob_triggers

(以Blob 类型存储的触发器。)—Trigger作为Blob类型存储–(用于Quartz用户用JDBC创建他们自己定制的 Trigger类型,JobStore并不知道如何存储实例的时候)

qrtz_calendars

(存放日历信息, quartz可配置一个日历来指定一个时间范围。)—-以Blob类型存储Quartz的Calendar信息

qrtz_cron_triggers

(注意:cron方式需要用到的4张数据表:qrtz_triggers,qrtz_cron_triggers,qrtz_fired_triggers, qrtz_job_details。)—(存放cron类型的触发器。)—(cron表达式)—-存储cron Trigger,包括Cron表达式和时区信息

qrtz_fired_triggers

(存放已触发的触发器。)—存储与已触发的Trigger相关的状态信息,以及相联Job的执行信息。(存储与已触发 的Trigger相关的状态信息,以及相联Job的执行信息)

qrtz_job_details

(存放一个jobDetail信息。)—保存job详细信息,该表需要用户根据实际情况初始化(存储每一个已配置的Job的详细 信息)

qrtz_locks

(存储程序的悲观锁的信息(假如使用了悲观锁)。)–tables_oracle.sql里有相应的dml初始化(存储程序的悲观锁的信息 (假如使用了悲观锁))

qrtz_paused_trigger_grps

(存放暂停掉的触发器。)—-存储已暂停的Trigger组的信息

qrtz_scheduler_state

(调度器状态。)—-(运行中实例的状态)—集群中节点实例信息,Quartz定时读取该表的信息判断集群中每 个实例的当前状态。(存储少量的有关Scheduler的状态信息,和别的Scheduler实例(假如是用于一个集群中))

qrtz_simple_triggers

(简单触发器的信息。)—存储简单的Trigger,包括重复次数,间隔,以及已触的次数

qrtz_triggers

(触发器的基本信息。)—(持久化任务:当应用程序停止运行时,所有调度信息不被丢失,当你重新启动时,调度 信息还存在,这就是持久化任务(保存到数据库表中)。)—(每个定时任务的上次及下次执行时间, 执行状态 (BLOCKED,WAITING等))存储已配置的Trigger

spring-task.xml:进行任务配置,以及定时引用任务,最后将定时任务丢进任务工厂,并引入quartz.properties配置文件

spring-config.xml:引入spring-task.xml

service :在相应service层写好任务方法

在继承QuartzJobBean的Job中注入相应service,并调用任务

总结:对于定时任务被持久化到数据库中,如果需要重新制作定时任务,需要将这几张数据库表中的无关记录删除掉,特别注意 qrtz_job_details这张表由于主外键关联,需要等到其它表无关记录删除之后,再进行删除。

quartz配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
spring:
quartz:
job-store-type: jdbc #将任务持久化到数据库
properties:
org:
quartz:
scheduler:
instanceName: DtsScheduler #scheduler的实例名,quartz集群该配置需要相同
instanceId: AUTO #分布式节点ID自动生成
jobStore:
class: org.quartz.impl.jdbcjobstore.JobStoreTX
driverDelegateClass: org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
tablePrefix: QRTZ_ #表示数据库中相关表是QRTZ_开头的
useProperties: false #不使用properties加载 使用yml配置
isClustered: true #开启集群,多个Quartz实例使用同一组数据库表
clusterCheckinInterval: 10000 #分布式节点有效性检查时间间隔,单位:毫秒
misfireThreshold: 36000000 #任务没有被触发的阈值,配置10h,单位ms
maxMisfiresToHandleAtATime: 20 #默认20,最大支持的数量
threadPool:
class: org.quartz.simpl.SimpleThreadPool
threadCount: 50 # 50
threadPriority: 5
threadsInheritContextClassLoaderOfInitializingThread: true

因为需要配置成集群的模式,这里所有的任务数据需要记录到数据库中间。而以往默认创建的scheduler都是将任务数据记录在ramstore里,也就是这些数据都保存在内存中。另外,既然在多个节点中执行任务,每个任务执行的时间长短已经启动的时间点都不一样。所以需要为它们安排一个线程池来方便调度。同时,多个节点的更新都要访问数据库,所以这里对数据库的连接也最好使用连接池。前面的示例中使用了oracle的thin连接,并将线程池的容量配置成25个。
这种模型是怎么保证系统的高可用性和性能的呢?在这里,因为每个节点都执行不同的job,我们必须保证对于给定的任务只是在单独的一个节点上执行。所以当cluster里最先能够抢占到该任务的节点执行的时候,它会对数据库里对应这个任务的行加锁,然后后续的就不能再去占用了。通过利用锁的机制,这里也比较容易实现一个负载均衡,每次节点只要去取到那些没有被加锁的任务执行就可以了。