Quartz 学习笔记(二)任务调度框架 | 任务持久化 | SpringBoot 整合 Quartz 入门案例 | 通过web控制调度器的启动、暂停、继续和停止

参考资料

官方GitHub :https://github.com/quartz-scheduler/quartz

官方 JobStores 帮助文档:https://github.com/quartz-scheduler/quartz/blob/master/docs/tutorials/tutorial-lesson-09.md

Quartz框架中实现工作持久化的组件是 JobStore,接下来让我们一起学习这个组件的概念与使用。

一、JobStore 持久化


JobStore 负责存储并提供给 scheduler 所有的 work data,例如 Job、Trigger、Calendars 等等,

Qquartz 调度程序实例选择合适的 JobStore 是比较关键的步骤,官方建议在 SchedulerFactory 生成 Scheduler 实例时指定 JobStore,或者通过配置文件指定。

官方说到切勿在代码中直接使用 JobStore实例,我们只需要通过调用 Scheduler 接口来使用 JobStore。

1.1 不同 JobStore的比较

1.1.1 RAMJobStore

是使用方式最常见的 JobStore,同时也是性能最高的(在CPU层面)。
RAMJobStore 会将所有数据保存在RAM中。
优点:

  • 数据存取速度快

缺点:

  • 应用程序结束或者崩溃时,所有调度信息都将丢失
  • 无法遵守作业和触发器的 “non-volatility” 非波动性的设置

使用方式:配置指定官方提供的类即可(默认选择的就是这个)

org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore

1.1.2 JDBCJobStore

通过 JDBC操作 将所有数据都保存在数据库。

优点:

  • 支持持久化
  • 几乎支持任何数据库,比如 Oracle、PostgreSQL、MYSQL、HSQLDB等

缺点:

  • 性能比 RAMJobStore 低很多

使用方式:

  1. 准备数据表,创建一组数据表供 Quartz 使用,这在 Quartz 源码中是有提供的,而且有不同数据库语言的SQL脚本,之后我们以MYSQL为主进行测试。表的规范有:所有表都以 qrtz_开头,例如 qrtz_triggersqrtz_job_detail。当然,这个表名前缀可以自己指定,官方默认的是 qrtz_
  2. 选择事务,指定数据表以后需要指定事务,通常选择 JobStoreTX,不需要将调度命令(如添加和删除触发器)操作绑定到其他事务,第二个是 JobStoreCMT,这种情况下 Quartz 将会让容器来管理事务。
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
  1. 选择驱动代理 DriverDelegate ,接下来需要选择一个 驱动代理 DriverDelegate 供 JobStore 使用。

DriverDelegate 负责执行特定数据库可能需要的任何 JDBC 工作,最常用的是 StdJDBCDelegate,这是一个使用“普通”JDBC 代码(和 SQL 语句)来完成其工作的代理。其他代理可以在org.quartz.impl.jdbcjobstore包或其子包中找到。

  1. 配置表名前缀,默认为 qrtz_
org.quartz.jobStore.tablePrefix = qrtz_
  1. 最后,指定 DataSource数据源,这使得 JDBCJobStore可以从DataSource获取到数据库的连接。
org.quartz.dataSource.myDs.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.myDs.URL = jdbc:mysql://localhost:3306/qrtz
org.quartz.dataSource.myDs.user = root
org.quartz.dataSource.myDs.password = root
    
org.quartz.jobStore.dataSource = myDs

官方建议:如果调度程序很忙(即几乎总是执行与线程池大小相同数量的Job,那么应该将 DataSrouce中的连接数设置为大约线程池的大小 + 2)

// 官方建议的配置,指定 JDBCJobStore jobDataMaps 中的所有值都是字符串
// 支持存储 K-V键值对
// 提升安全性,避免了将非字符串序列化为BLOB时存在的类版本控制问题
org.quartz.jobStore.useProperties = true

1.2.3 TarractottaJobStore

TarractottaJobStore 提供了一种在不使用数据库的情况下实现扩展和健壮性的方法。

优点:

  • 支持集群或非集群两种场景,且都支持存储
  • 性能比 JDBCStore更高,但低于 RAMJobStore

使用方式:(直接配置官方提供的类还有URL即可)

org.quartz.jobStore.class = org.terracotta.quartz.TerracottaJobStore
org.quartz.jobStore.tcConfigUrl = localhost:9510

1.2.4 使用建议

官方关于对job持久化使用的建议:https://github.com/quartz-scheduler/quartz/blob/master/docs/index.adoc#jdbc-jobstore

1)永远不要直接写数据到 Quartz 的表
调度数据应直接写入数据库(通过 SQL)而不是使用调度 API,否则可能会出现以下问题:

① 导致数据损坏(已删除数据、带干扰数据)
② 触发器执行时,导致作业看似“消失”而不执行
③ 触发器执行时,导致作业不执行,但是占用着资源
④ 可能导致:死锁
⑤ 其他奇怪的问题和数据损坏

2)切勿将非集群调度程序与具有相同调度程序名称的另一个调度程序指向同一数据库

如果将多个调度程序实例指向同一组数据库表,并且其中一个或多个实例未配置为集群,则可能会发生和以上五种情况一样的问题。

3)确保足够的数据源连接大小

建议 DataSource 最大连接大小至少配置为线程池中的工作线程数加 3。如果应用程序还频繁调用调度程序 API,最好设置更多的连接。如果使用 JobStoreCMT,“non managed”数据源的最大连接大小应至少为 4

二、Quartz 持久化案例( JDBCJobStore)

运行效果:

在这里插入图片描述

2.1 导入 Quartz 官方的 SQL 文件

官方下载源码压缩包:http://www.quartz-scheduler.org/downloads/

src/org/quartz/impl/jdbcjobstore/*.sql
在这里插入图片描述

这些sql文件是quartz框架针对不同的数据库设计的,这里我选择执行tables_mysql.sql,内容如下:

#
# Quartz seems to work best with the driver mm.mysql-2.0.7-bin.jar
#
# PLEASE consider using mysql with innodb tables to avoid locking issues
#
# In your Quartz properties file, you'll need to set
# org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#

DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
DROP TABLE IF EXISTS QRTZ_LOCKS;
DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
DROP TABLE IF EXISTS QRTZ_CALENDARS;


CREATE TABLE QRTZ_JOB_DETAILS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    JOB_NAME  VARCHAR(200) NOT NULL,
    JOB_GROUP VARCHAR(200) NOT NULL,
    DESCRIPTION VARCHAR(250) NULL,
    JOB_CLASS_NAME   VARCHAR(250) NOT NULL,
    IS_DURABLE VARCHAR(1) NOT NULL,
    IS_NONCONCURRENT VARCHAR(1) NOT NULL,
    IS_UPDATE_DATA VARCHAR(1) NOT NULL,
    REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
    JOB_DATA BLOB NULL,
    PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
);

CREATE TABLE QRTZ_TRIGGERS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    JOB_NAME  VARCHAR(200) NOT NULL,
    JOB_GROUP VARCHAR(200) NOT NULL,
    DESCRIPTION VARCHAR(250) NULL,
    NEXT_FIRE_TIME BIGINT(13) NULL,
    PREV_FIRE_TIME BIGINT(13) NULL,
    PRIORITY INTEGER NULL,
    TRIGGER_STATE VARCHAR(16) NOT NULL,
    TRIGGER_TYPE VARCHAR(8) NOT NULL,
    START_TIME BIGINT(13) NOT NULL,
    END_TIME BIGINT(13) NULL,
    CALENDAR_NAME VARCHAR(200) NULL,
    MISFIRE_INSTR SMALLINT(2) NULL,
    JOB_DATA BLOB NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
        REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)
);

CREATE TABLE QRTZ_SIMPLE_TRIGGERS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    REPEAT_COUNT BIGINT(7) NOT NULL,
    REPEAT_INTERVAL BIGINT(12) NOT NULL,
    TIMES_TRIGGERED BIGINT(10) NOT NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
quartz框架是一个开源的Java调度框架,可用于编写定时任务。而Spring Boot是一个用于简化Java应用开发的框架。在将quartz框架Spring Boot整合时,我们可以通过使用new的方式来编写定时任务。 首先,在Spring Boot的主配置类上加上@EnableScheduling注解,以启用定时任务的支持。然后,我们可以创建一个新的类并实现org.springframework.scheduling.annotation.SchedulingConfigurer接口,这个接口提供了定时任务的配置信息。在该类中,我们可以使用@Bean注解来定义一个定时任务,并设置其触发时间、逻辑等。 在定义定时任务的方法上,我们可以使用@Scheduled注解来指定任务的执行方式和触发时间。例如,可以使用@Scheduled(fixedRate = 5000)来表示每隔5秒执行一次该任务,或者使用@Scheduled(cron = "0 0 12 * * ?")来表示每天中午12点执行一次任务。 需要注意的是,在使用new的方式编写定时任务时,我们需要手动将该任务注册到quartz框架中。我们可以在Spring Boot的配置类中通过创建org.springframework.scheduling.quartz.SchedulerFactoryBean对象来获取一个Quartz调度实例。然后,再使用调度实例的scheduleJob方法来注册定时任务。 总的来说,通过new的方式编写定时任务的步骤如下: 1. 在Spring Boot的主配置类上加上@EnableScheduling注解,启用定时任务的支持。 2. 创建一个新的类并实现SchedulingConfigurer接口,用于配置定时任务。 3. 在配置类中定义定时任务的方法,并使用@Scheduled注解指定任务的执行方式和触发时间。 4. 在配置类中获取Quartz调度实例,并使用调度实例的scheduleJob方法来注册定时任务。 这样,我们就可以使用new的方式编写定时任务,并实现quartz框架Spring Boot整合
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值