定时任务框架Quartz的存储方式持久化与集群配置

引言

前面的博文介绍了Quartz定时任务框架的相关知识,以及如何与Spring进行集成。本文将继续介绍Quartz的存储方式以及集群配置。

存储方式

一、存储方式 RAMJobStore和JDBCJobStore

Quartz提供两种基本作业存储类型。第一种类型叫做RAMJobStore,第二种类型叫做JDBC作业存储。在默认情况下Quartz默认使用RAMJobStore存储方式将任务调度的运行信息保存在内存中,这种方法提供了最佳的性能,因为内存中数据访问最快且配置容易。不足之处是缺乏数据的持久性,当程序中途停止或系统崩溃时,所有运行的信息都会丢失。但是使用JDBCJobStore 可以通过调整属性,将调度信息保存到数据库中,当系统崩溃或者停止再运行后,任务的调度进行将从中断处得到回复并继续运行。可以持久化的运行调度任务。
对比图:

类型优点缺点
RAMJobStore(默认)不要外部数据库,配置容易,运行速度快因为调度程序信息是存储在被分配给JVM的内存里面,所以,当应用程序停止运行时,所有调度信息将被丢失。另外因为存储到JVM内存里面,所以可以存储多少个Job和Trigger将会受到限制
JDBCJobStore支持集群,因为所有的任务信息都会保存到数据库中,可以控制事物,还有就是如果应用服务器关闭或者重启,任务信息都不会丢失,并且可以恢复因服务器关闭或者重启而导致执行失败的任务运行速度的快慢取决与连接数据库的快慢

二、设置 JDBCJobStore

1、创建quartz数据库表
在应用程序中设置使用 JDBCJobStore 需要两步:首先必须创建作业仓库使用的数据库表。 JDBCJobStore与所有主流数据库都兼容,而且quartz提供了一些了创建表的SQL脚本。
SQL脚本的位置:
可以在 下载的jar包中进行解压缩获取,例如maven仓库中找到jar包:
在这里插入图片描述
解压缩打开之后,在quartz-2.3.0.jar\org\quartz\impl\jdbcjobstore下,针对你需要的sql文件执行即可。
在这里插入图片描述
我所使用的数据库为mysql数据库,所以新建quartz数据库执行tables_mysql_innodb.sql文件刷新后得到结果如下,共计十一张表。
在这里插入图片描述
2、创建quartz数据库运行sql导入库表之后,在quartz.properties中指定 JDBCJobStore 属性。
配置文件如图:

org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 10
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true


# Using RAMJobStore
## if using RAMJobStore, please be sure that you comment out the following
## - org.quartz.jobStore.tablePrefix,
## - org.quartz.jobStore.driverDelegateClass,
## - org.quartz.jobStore.dataSource
# org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore


# Using JobStoreTX
## Be sure to run the appropriate script(under docs/dbTables) first to create tables
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX

# Configuring JDBCJobStore with the Table Prefix

org.quartz.jobStore.tablePrefix = QRTZ_

# Using DriverDelegate
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate

# Using datasource
org.quartz.jobStore.dataSource = qzDS

# Define the datasource to use
org.quartz.dataSource.qzDS.driver = com.mysql.cj.jdbc.Driver
org.quartz.dataSource.qzDS.URL = jdbc:mysql://localhost:3306/quartz?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
org.quartz.dataSource.qzDS.user = root
org.quartz.dataSource.qzDS.password = 123456
org.quartz.dataSource.qzDS.maxConnections = 30

3、spring-quartz.xml文件如下

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--job-->
  <!--  <bean id="MyQuartzJob" class="com.hbc.springboot.quartz.MyQuartzJob"></bean>-->
    <!--创建JobDetail-->
    <bean id= "jobDetail"
        class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
        <!--指定任务类-->
        <property name="jobClass" value="com.hbc.springboot.quartz.MyQuartzJob"></property>
        <!--当Job在没有可以使用的trigger的情况下 不删除-->
        <property name="durability" value="true"></property>
    </bean>
        <!--注意spring quartz整合 一个trigger只可以绑定一个JobDetail 一个jobDetail可以被多个Trigger所使用-->
    <bean id="trigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <!--绑定JobDetail-->
        <property name="jobDetail" ref="jobDetail"></property>
        <property name= "cronExpression" value="0-30 * * * * ?"></property>
    </bean>
    <bean id="trigger1"
        class= "org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <!--绑定JobDetail-->
        <property name="jobDetail" ref="jobDetail"></property>
        <property name="cronExpression" value="45-55 * * * * ?"></property>
    </bean>
    <!--注册trigger -->
    <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <!--引入配置文件quartz.properties -->
        <property name="configLocation" value="classpath:quartz.properties"/>
        <property name= "triggers">
            <list>
                <ref bean= "trigger"></ref>
                <ref bean= "trigger1"></ref>
            </list>
        </property>
    </bean>
</beans>

4、任务类 如下:

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import java.util.Date;


/**
 * 定义要执行的任务内容
 */
public class MyQuartzJob implements Job{
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        //输出系统当前时间
        System.err.println("系统当前时间为+"+new Date());
    }
}

5、测试
使用Spring工厂进行测试

import org.springframework.context.support.ClassPathXmlApplicationContext;


public class SpringQuartzTest {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext classPathXmlApplicationContext
                = new ClassPathXmlApplicationContext("spring-quartz.xml");
    }
}

6、结果可以看到JDBCJobStore持久化配置成功
在这里插入图片描述
并看到成功打印系统时间
在这里插入图片描述

集群支持

一、原理

虽然单个Quartz实例能给予你很好的Job调度能力,但它不能满足典型的企业需求,如可伸缩性、高可靠性满足。假如你需要故障转移的能力并能运行日益增多的Job, Quartz集群势必成为你应用的一部分了。使用Quartz的集群能力可以更好的支持你的业务需求,并且即使是其中一台机器在最糟的时间崩溃了也能确保所有的Job得到执行。
一个Quartz集群中的每个节点是一个独立的 Quartz应用,它又管理着其他的节点。意思是你必须对每个节点分别启动或停止。不像许多应用服务器的集群,独立的Quartz节点并不与另一其的节点或是管理节点通信。Quartz应用是通过数据库表来感知到另一应用的。
下图:表示了每个节点直接与数据库通信,若离开数据库将对其他节点一无所知
在这里插入图片描述

二、搭建步骤

1、准备配置文件 quartz.properties

# 调度标识名集群中每一个实例都必须使用相同的名称
org.quartz.scheduler.instanceName=TestScheduler
# ID设置为自动获取 每一个必须不同
org.quartz.scheduler.instanceId: auto

org.quartz.scheduler.skipUpdateCheck=true

org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
# 线程数量
org.quartz.threadPool.threadCount = 10
# 线程优先级
org.quartz.threadPool.threadPriority = 5
# 自创建父线程
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true

# 默认配置,数据保存到内存
# org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore

# 持久化配置
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.isClustered = true


# 数据库表前缀
org.quartz.jobStore.tablePrefix = QRTZ_
#设置为TRUE不会出现序列化非字符串类到 BLOB 时产生的类版本问题
org.quartz.jobStore.useProperties = true

# Using DriverDelegate
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate

# Using datasource
org.quartz.jobStore.dataSource = qzDS

# Define the datasource to use
org.quartz.dataSource.qzDS.driver = com.mysql.cj.jdbc.Driver
org.quartz.dataSource.qzDS.URL = jdbc:mysql://localhost:3306/quartz?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
org.quartz.dataSource.qzDS.user = root
org.quartz.dataSource.qzDS.password = 123456
org.quartz.dataSource.qzDS.maxConnections = 30

2、spring-quartz.xml以及任务类和上面一样,启动Spring工厂测试即可。
在这里插入图片描述
我们可以看到现在采用JDBCJobStore持久化存储方式,并且集群配置成功。

总结

以上就是定时任务框架Quartz的存储方式持久化与集群配置,文章步骤详细,操作简单,逐步按照教程操作即可。
另外对quartz库表进行相关说明:

表名称说明
qrtz_blob_triggersTrigger作为Blob类型存储(用于Quartz用户用JDBC创建他们自己定制的Trigger类型,JobStore 并不知道如何存储实例的时候)
qrtz_calendars以Blob类型存储Quartz的Calendar日历信息, quartz可配置一个日历来指定一个时间范围
qrtz_cron_triggers存储Cron Trigger,包括Cron表达式和时区信息。
qrtz_fired_triggers存储与已触发的Trigger相关的状态信息,以及相联Job的执行信息
qrtz_job_details存储每一个已配置的Job的详细信息
qrtz_locks存储程序的非观锁的信息(假如使用了悲观锁)
qrtz_paused_trigger_graps存储已暂停的Trigger组的信息
qrtz_scheduler_state存储少量的有关 Scheduler的状态信息,和别的 Scheduler 实例(假如是用于一个集群中)
qrtz_simple_triggers存储简单的 Trigger,包括重复次数,间隔,以及已触的次数
qrtz_triggers存储已配置的 Trigger的信息
qrzt_simprop_triggers
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 C# ,可以使用 Quartz.NET 来实现定时任务,同时支持数据持久化Quartz.NET 是一个功能强大且灵活的开源作业调度库,可以用于创建定时任务和计划任务,支持数据持久化集群部署等高级功能。 要使用 Quartz.NET 实现数据持久化,需要先创建一个用于存储调度程序数据数据库表,可以使用 Quartz.NET 提供的 SQL 脚本来创建表。然后在应用程序配置 Quartz.NET,指定数据库类型和连接字符串等信息。示例如下: ```csharp using Quartz; using Quartz.Impl; using Quartz.Impl.AdoJobStore; using Quartz.Spi; using System; using System.Collections.Specialized; class Program { static void Main() { Console.WriteLine("Starting scheduler..."); // 创建一个调度程序实例 ISchedulerFactory schedulerFactory = new StdSchedulerFactory(GetSchedulerProperties()); IScheduler scheduler = schedulerFactory.GetScheduler().Result; // 启动调度程序 scheduler.Start(); Console.WriteLine("Scheduler started."); // 创建一个作业实例 IJobDetail job = JobBuilder.Create<HelloJob>() .WithIdentity("job1", "group1") .Build(); // 创建一个触发器实例,每秒钟触发一次 ITrigger trigger = TriggerBuilder.Create() .WithIdentity("trigger1", "group1") .StartNow() .WithSimpleSchedule(x => x .WithIntervalInSeconds(1) .RepeatForever()) .Build(); // 将作业和触发器添加到调度程序 scheduler.ScheduleJob(job, trigger); // 等待用户按下 Enter 键退出 Console.ReadLine(); // 关闭调度程序 scheduler.Shutdown(); Console.WriteLine("Scheduler stopped."); } static NameValueCollection GetSchedulerProperties() { // 配置调度程序属性,指定数据持久化和相关参数 NameValueCollection properties = new NameValueCollection(); properties["quartz.scheduler.instanceName"] = "MyScheduler"; properties["quartz.scheduler.instanceId"] = "AUTO"; properties["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz"; properties["quartz.jobStore.driverDelegateType"] = "Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz"; properties["quartz.jobStore.dataSource"] = "default"; properties["quartz.dataSource.default.provider"] = "SqlServer-20"; properties["quartz.dataSource.default.connectionString"] = "Server=(local);Database=Quartz;Trusted_Connection=True;"; return properties; } } public class HelloJob : IJob { public void Execute(IJobExecutionContext context) { Console.WriteLine("Hello, Quartz.NET!"); } } ``` 这个示例创建一个调度程序实例,然后创建一个作业实例和触发器实例,并将它们添加到调度程序。作业类 HelloJob 实现了 IJob 接口,用于定义作业执行的逻辑。在 GetSchedulerProperties 方法配置了调度程序属性,指定了数据库类型和连接字符串等信息。在这个示例,使用的是 SQL Server 数据库。 需要注意的是,在使用 Quartz.NET 进行数据持久化时,需要保证数据库连接可靠和高效,同时需要考虑并发执行的问题。可以适当地调整作业和触发器的参数,以达到最优的性能和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值