【Quartz】(一)定时框架Quartz的持久化配置

Quartz的持久化数据库(九) > 勿以恶小而为之,勿以善小而不为--------------------------刘备 > 劝诸君,多行善事积福报,莫作恶 主要内容: Quartz的持久化和动态添加任务 阅读详情

1. 使用背景

当前,越来越多的场景下面需要使用到定时任务,比如报表的生成,每月或者每年进行一次某些数据的统计等等,使用Springboot中的@Scheduled注解固然也可以实现,只不过,如果要改定时的时间,控制定时的开关,都需要直接操作项目的代码,如果是线上环境的,还得需要把项目 停下来,代价太大,那到底有没有一种框架可以实现我们对于定时任务的增删查改,可以修改定时的时间,启动以及暂定定时任务呢,答案是有的,目前定时任务的框架有很多,比如我们今天要说的Quartz,分布式定时任务xxl-job等等。

2.Quartz持久化定时任务的原理

Quartz的依赖

    <dependency>
      <groupId>org.quartz-scheduler</groupId>
      <artifactId>quartz</artifactId>
      <version>2.3.0</version>
    </dependency>

打开Quartz包下的路径org.quartz.impl.jdbcjobstore可以看到有很多的sql
在这里插入图片描述
这些Sql文件是quartz针对不同的数据库设计的,我们使用的是Mysql,所以我们将tables_mysql_innodb.sql在数据库里面跑一下,看下效果
在这里插入图片描述
看到默认帮我们生成了这11张表,通过分析这些表,我们就能大致了解Quartz实现定时任务持久化的原理。

表名含义
qrtz_blob_triggers存储用户自定义的trigger,实现Trigger等接口实现自定义逻辑
qrtz_calendars存储和触发器关联的日期
qrtz_cron_triggers存储cron类型的触发器
qrtz_fired_triggers存储正在执行的任务
qrtz_job_details存储任务的详细信息
qrtz_locks存储执行任务需要获取的锁
qrtz_paused_trigger_grps存储被暂停的触发器组
qrtz_scheduler_state存储集群环境的状态
qrtz_simple_triggers存储简单触发器
qrtz_simprop_triggers存储CalendarIntervalTrigger和DailyTimeIntervalTrigger
qrtz_triggers存储任务执行的时间,下次执行时间,任务执行的状态等信息

其实quartz的执行逻辑很简单,就是从qrtz_triggers获取等待状态将要执行的任务,通过关联查询,查询对应的触发器,以及job_details中任务执行的类进行任务的执行,简单的来说,就是这样的。

3. 持久化配置

我这里以Springboot配置为例,讲解一下如何进行配置。

定义一个Quartz的配置类QuartzConfig

@Configuration
public class QuartzConfig{
	
	@Bean
    public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource){
        SchedulerFactoryBean factory = new SchedulerFactoryBean();
        // 设置数据源,这个数据源是从Bean获取来的,可以在Bean里面配置任意的数据库
        factory.setDataSource(dataSource);
		
        Properties prop = new Properties();
        // 集群环境的唯一ID,名字可以任意设置,instanceId设置成AUTO,系统会帮我们自动生成 
        prop.put("org.quartz.scheduler.instanceName", "MyScheduler");
        prop.put("org.quartz.scheduler.instanceId", "AUTO");
        // 配置Quartz运行的线程池配置
        prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
        prop.put("org.quartz.threadPool.threadCount", "20");
        prop.put("org.quartz.threadPool.threadPriority", "5");
        // 非常重要!JDBC的增删查改都是依靠JobStore来完成的。
        prop.put("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX");
        // 配置集群环境
        prop.put("org.quartz.jobStore.isClustered", "true");
        prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000");
        prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1");
        prop.put("org.quartz.jobStore.txIsolationLevelSerializable", "true");
        //若集群环境需要配置此项,可防止重复执行,单机环境不推荐配置此项,会消耗服务器性能
        //prop.put("org.quartz.jobStore.acquireTriggersWithinLock","true");

        
        prop.put("org.quartz.jobStore.misfireThreshold", "12000");
        prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_");
        factory.setQuartzProperties(prop);

        factory.setSchedulerName("MyScheduler");
        // 延时启动
        factory.setStartupDelay(1);
        factory.setApplicationContextSchedulerContextKey("applicationContextKey");
        // 可选,QuartzScheduler
        // 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了
        factory.setOverwriteExistingJobs(true);
        // 设置自动启动,默认为true
        factory.setAutoStartup(true);

        return factory;
    }
}

4.持久化一些简单的实现

我们首先定义一个Job,我希望这个Job帮我打印字符串

public class TestTask implements Job {
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("Hello");
    }
}

然后我们告诉Quartz,申请一个名称为job1,组为group1的JobDetails帮我们记录这个Job

@RestController
@RequestMapping("/job")
public class JobController {
	
	@Autowired
    private Scheduler scheduler;

	@RequestMapping("createJob")
	public String createJob() throws SchedulerException {
		JobDetail jobDetail = JobBuilder.newJob(TestTask.class).withIdentity("job1", "group1").build();
		return "created!";
	}
}

光这样还不行,我们还要申请一个名称为trigger1,组为tgroup1的Cron类型的触发器,告诉Quartz这个任务执行的周期

@RestController
@RequestMapping("/job")
public class JobController {
	
	@Autowired
    private Scheduler scheduler;

	@RequestMapping("createJob")
	public String createJob() throws SchedulerException {
		JobDetail jobDetail = JobBuilder.newJob(TestTask.class).withIdentity("job1", "group1").build();
		CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "tgroup1")
                .withSchedule(CronScheduleBuilder.cronSchedule("* * * * *  ?")).build();
		return "created!";
	}
}

然后通过Quartz的调度器,帮我们执行的任务,通过我们创建的Cron的触发器

@RestController
@RequestMapping("/job")
public class JobController {
	
	@Autowired
    private Scheduler scheduler;

	@RequestMapping("createJob")
	public String createJob() throws SchedulerException {
		JobDetail jobDetail = JobBuilder.newJob(TestTask.class).withIdentity("job1", "group1").build();
		CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "tgroup1")
                .withSchedule(CronScheduleBuilder.cronSchedule("* * * * *  ?")).build();
        scheduler.scheduleJob(jobDetail,trigger);
        scheduler.start();
		return "created!";
	}
}

启动项目
此时观察表,可以发现
qrtz_scheduler_state已经记录了我们的第一台的机器的信息
在这里插入图片描述
此外,qrtz_locks里面也帮我们生成了两把锁,关于这个锁的含义,下一篇博客中,我会和大家讲解一下含义
在这里插入图片描述
其他表里面暂时没有数据了,那么现在我们我们利用我们刚刚写的那个接口帮我们创建一个job试一下

http://ip:端口/job/createJob

在这里插入图片描述
可以看到此时任务一直在重复执行
我们再来看一下表里面发生了哪些数据的改变
首先qrtz_cron_triggers,帮我们新增了一条我们刚刚定义的cron的trigger
在这里插入图片描述
qrtz_job_details,也帮我们新建了一条任务的详情,记录了任务执行类的全限定名
在这里插入图片描述
qrtz_fired_triggers记录了此时此刻,我们正在执行的定时任务
在这里插入图片描述
qrtz_triggers记录了我们已有任务的一些信息,包括上一次执行的时间,下一次执行的时间,以及任务此时的状态等
在这里插入图片描述
看到这里,相信大家应该觉得Quartz不过如此,非常的简单,但是如果仅仅是这样使用也会产生某些问题,后面的博客中,我将详细介绍一下,集群环境下Quartz重复执行产生的原因,以及如何去解决重复执行的问题,包括我们如果在一个Springboot项目中如何优雅的使用Quartz,我们可以在页面中,增删查改定制化我们的任务。

Quartz 持久化实现详解 项目通过 `QuartzJobFactory` 实现了与 Spring 的集成:它的主要作用是解决 Quartz 任务类中无法直接使用 Spring 依赖注入的问题。任务需要实现 `Job` 接口,并在 `execute` 方法中实现具体的业务逻辑。- `qrtz_job_details`: 存储作业的详细信息,包括作业名称、组、类名等。- `qrtz_paused_trigger_grps`: 记录暂停的触发器组。- `qrtz_simprop_triggers`: 存储带属性的触发器。 阅读详情

相关推荐

springboot整合quartz实现任务持久化(下)

主要介绍 spring-boot-starter-quartz 的使用技巧

On the road to profession 3263

Quartz定时框架的持久化

小强的上一篇quartz文章简单的说了一下quartz的怎样使用,一般在实际工作中那个根本是不够的,所以今天在这记录下Quartz定时框架的持久化, 一、quartz的存储于持久化介绍 Quartz框架有两种任务存储方式。一种是RAMJobStore存储方式,也是默认的存储方式。RAMJobStore将quartz定时的任务信息存储在服务器的内存中,这种方式的优点是可以提供最好的性能,因为任...

Mr.小强的博客 7658

SpringBoot中实现定时任务(Quartz)

在 SpringBoot 中实现定时任务的方法,包括使用 Spring Task 的单线程和多线程执行任务,使用第三方框架 Quartz 实现定时任务,详细说明了 JobDetail 和 Trigger 触发器的配置,还介绍了 cron 表达式的格式、元素、通配符含义及示例,以及分布式任务调度平台 XXL-JOB。

Mervin 905

Quartz 定时任务

Quartz部署了多个节点,为啥总是在特定节点执行 Quartz集群 使用数据库来进行集群的管理 QRTZ_SCHEDULER_STATE表用来存储各个实例,如下:前两个是运行在同一台Linux上的两个jar包。第三个是运行在一台windows上的jar包。 其中last_checkin_time是每个实例,自己报告的最后时间。 实例在更新自己的last_checkin_time时还会监测其他节点的,如果其他节点在last_checkin_time+last_checkin_tim<.

leoppeng的专栏 4404

【Quartz】Quartz定时任务框架

Quartz是一个框架,是SpringBoot御用的定时任务框架,有三大核心部分组成,分别是JobTriggerScheduler。Job:任务,可以理解成你要做什么事,具体要执行的业务逻辑,比如:发送短信、同步数据、发送邮件等。Trigger:触发器,可以理解成你什么时候去做,用来定义Job触发条件、触发时间、触发间隔、终止时间等。Scheduler:调度器,可以理解成你什么时候要去做什么事,它会启动Trigger去执行Job。/*** @author : 黎剑。

qq_22193961的博客 9087

Java定时框架Quartz实例详解与定时任务的Mongodb、Mysql持久化实现(三)Quartz持久化

就像我在上一篇中说的,把调度器信息存储在内存中非常的快也易于配置。但当调度器进程一旦被终止,所有的 Job 和 Trigger 的状态就丢失了。所以我们就需要把调度器信息持久化到数据库,在服务器重启时就可以自动启动终止的任务。Quartz不可能没有考虑到这个问题,可以通过引入Jar包与配置实现,并支持多种数据库版本。 一、持久化到MongoDB 1、引入Jar依赖 好吧,我承认,这竟然是我做

Leeon的博客 5955

SpringBoot(二)集成 Quartz

Quartz是一个广泛使用的开源任务调度框架,用于在Java应用程序中执行定时任务和周期性任务。它提供了强大的调度功能,允许您计划、管理和执行各种任务,从简单的任务到复杂的任务。

SpringHASh的博客 3861

【QUARTZ】springboot+quartz动态配置定时任务

​ Quartz 定时任务可分为Trigger(触发器)、Job(任务)和Scheduler(调度器),定时任务的逻辑大体为:创建触发器和任务,并将其加入到调度器 ​

niuchenliang524的博客 2801

Quartz 定时任务框架介绍

Quartz Scheduler 是一个 Java 的“任务调度框架(Job Scheduling Framework)”。在指定时间、按指定规则,自动执行某些 Java 代码。Quartz 最常用的是 Cron。Quartz 集群本质依赖数据库锁。Quartz 可以把任务存数据库。Quartz 专门解决这些问题。默认 Quartz 是内存模式。Quartz 支持给任务传参。Quartz 自己维护线程池。Job 就是真正执行的任务。Quartz 多一位“秒”。Quartz 仍然大量存在。

西凉的悲伤博客 525

Java定时框架Quartz实例详解与定时任务的Mongodb、Mysql持久化实现(一)Quartz组件

一、Quartz概述 Quartz是一个完全由Java编写的开源作业调度框架,为在Java应用程序中进行作业调度提供了简单却强大的机制。Quartz允许开发人员根据一定的时间间隔来调度作业。我学一样东西,从来都是从实践出发,边用边学,用起来自然就学会了。 二、使用Quartz 1、Quartz Jar 我推荐大家使用Maven来加入Jar依赖,方便而且可以对依赖有效地管理。

Leeon的博客 5514

Java定时框架Quartz实例详解与定时任务的Mongodb、Mysql持久化实现(二)Quartz配置文件

Quartz核心配置文件quartz.properties常见配置详解(配置在classpath中或在web.xml中指定,示例附在最后) 一、调度器属性配置 1、instanceName属性,调度器实例名,可以设定任意字符串,QuartzSheduler也是不设定的默认值,它通常应用于Quartz集群环境,以区别不同的调度器。 2、instanceId属性,调度器实例ID,和insta

Leeon的博客 2678

Quartz.NET 4.x 快速入门指南:从安装到第一个定时任务

Quartz.NET 是一个功能强大的开源作业调度库,专为 .NET 平台设计。它可以帮助开发人员在应用程序中实现各种定时任务,从简单的周期性任务到复杂的分布式作业调度都能胜任。本文将带你快速了解 Quartz.NET 4.x 的核心功能和使用方法。 ## 环境准备 ### 安装 Quartz.NET Quartz.NET 提供了多种安装方式,最便捷的是通过 NuGet 包管理器: 1. ...

gitblog_00301的博客 643

springboot集成定时任务框架quartz

springboot集成定时任务框架quartz quartz框架可以很方便的执行定时任务,任务可以持久化到数据库中,这里使用的数据库为postgres。 集成步骤: 1. quartz和数据库驱动maven依赖 &amp;lt;dependency&amp;gt; &amp;lt;groupId&amp;gt;org.quartz-scheduler&amp;lt;/groupId&amp;gt; ..

jacklife的博客 1602

定时任务框架Quartz-(一)Quartz入门与Demo搭建

一、什么是Quartz 什么是Quartz? Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,完全由Java开发,可以用来执行定时任务,类似于java.util.Timer。但是相较于Timer, Quartz增加了很多功能: 持久性作业 - 就是保持调度定时的状态; 作业管理 - 对调度作业进行有效的管理; ...

noaman_wgs的博客 39万+

Spring Boot中如何使用@Scheduled和Quartz实现定时任务?

🏆本文收录于《滚雪球学Spring Boot》,专门攻坚指数提升,2025 年国内最系统+最强(更新中)。    本专栏致力打造最硬核 Spring Boot 从零基础到进阶系列学习内容,🚀均为全网独家首发,打造精品专栏,专栏持续更新中…欢迎大家订阅持续学习。 如果想快速定位学习,可以看这篇【SpringBoot教程导航帖】,你想学习的都被收集在内,快速投入学习!!两不误。

**My Coding Family** 1480

Quartz 2.2.3:Java定时任务调度框架详解

Quartz作为一个开源的作业调度框架,广泛应用于企业级应用系统中,支持任务调度、作业管理等关键任务的自动化处理。掌握其核心概念是理解和使用Quartz的第一步。Quartz的架构由几个关键组件构成,每个组件都有其特定的功能和职责。核心组件包括:Scheduler:调度器,负责管理所有的任务调度和执行。Job:要执行的具体任务,是一个接口,通常需要实现其中的execute方法。JobDetail:描述Job的实例,包含Job的实现类以及属性等信息。Trigger。

weixin_35749786的博客 1041

quartz定时任务框架

简单介绍了quartz常见的操作,单机、集群环境的搭建等

qq_49949568的博客 2998

Python pydub实现语音停顿切分

将pcm文件批量处理成wav文件 import wave import os filepath = "data/" # 添加路径 filename = os.listdir(filepath) # 得到文件夹下的所有文件名称 #f = wave.open(filepath + filename[1], 'rb') #print(filename) for i in range(len(fi...

wangqianqianya的博客 1万+

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

引言 前面的博文介绍了Quartz定时任务框架的相关知识,以及如何与Spring进行集成。本文将继续介绍Quartz的存储方式以及集群配置。 存储方式 一、存储方式 RAMJobStore和JDBCJobStore Quartz提供两种基本作业存储类型。第一种类型叫做RAMJobStore,第二种类型叫做JDBC作业存储。在默认情况下Quartz默认使用RAMJobStore存储方式将任务调度的运...

爱学习的软件开发的博客 1236

G120变频器抱闸逻辑在提升机上应用

一、前言: 对于提升机、起重机、堆垛机、升降机等提升机构,负载为位能性负载,在设备启动和停止阶段,由于重物作用,可能会出现“溜车”现象、控制变频器与电机抱闸时许可以解决此问题 使用具有矢量控制功能的变频器 二、参数设置 抱闸控制时序: 启动: 1、变频器接收到启动命令时-----输出电流对电机进行励磁,经过P346电机励磁时间(==丹佛斯 设置启动电流延时0.5S)------达到一定的转矩 2、变频器输出开抱闸命令,经过P1216延时打开抱闸时间(==PLC延时控制打开抱闸) 注意:抱闸

fenglingxicao的博客 1万+

2026年软考信息安全工程师备考指南

信息安全工程师是信息产业部和人事部举办的软考中新增开的一门考试。软考全称全国计算机技术与软件专业技术资格(水平)考试,这门新开的信息安全工程师分属该考试“信息系统”专业,位处中级资格,是信息产业部和人事部在最新的“国人厅发[2007]139号文件中新增的专业。2016年下半年,第一次开考信息安全工程师(中级)考试。 考试科目: 1.信息安全基础知识,考试时间为150分钟,笔试,选择题; ...

鹿鸣天涯 7393
上一篇: 【Kafka】(二)Kafka去Zookeeper化,kraft模式搭建
下一篇: 【Xxl-Job】分布式定时任务解决方案-Xxl-Job的使用教程
JeffHan^_^
博客等级 码龄7年 1万+粉丝 134原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JeffHan^_^

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值