定时任务之Springboot整合Quartz详解

2023-11-07

背景:最近公司一个需求用到定时任务进行采集操作,故写文章来记录一下定时任务的基本概念

一、什么是Quartz

quartz是一个定时调度的框架,指定时间内触发执行某个动作;它完全由 Java 写成,并设计用于 J2SE 和 J2EE 应用中。

二、为什么使用Quartz

1、为什么要用定时任务

1)无需手动触发 :无需页面(人工)触发动作;
2)执行时间准确:会在准确的时间内进行业务处理;
3)低耦合:单独为一个动作体,可以自行开关,不影响其他业务功能;

2、为什么使用Quartz

1)目前公司使用较多的定时任务框架为xxl-Job,elastic-Job,此框架都是基于Quartz进行二次开发;
2)有些传统互联网公司定时任务框架还是使用Quartz

三、常见开源定时任务的框架的异同

在这里插入图片描述

四、Quartz的组件

在这里插入图片描述

1)Scheduler(调度器):Scheduler 是 Quartz 的核心组件,它负责管理和调度所有的任务。Scheduler 可以启动、停止、暂停和恢复任务的执行,还可以配置任务的触发条件和执行计划。
2)Job(任务):Job 是需要被调度执行的实际任务。您可以定义自己的 Job 类,实现自己的业务逻辑,并将其注册到 Scheduler 中。Quartz 提供了不同类型的 Job,如无状态的 Job、有状态的 Job 等,以满足不同的需求。
3)Trigger(触发器):Trigger 负责定义任务的触发条件,即何时触发任务的执行。您可以为每个 Job 关联一个或多个 Trigger,根据时间表达式(如 Cron 表达式)或者特定的时间间隔来配置触发器。
4)JobDetail(任务详情):JobDetail 是与 Job 相关联的详细信息,包括 Job 的名称、所属的 Job 类、Job 的身份标识等。每个 Job 都有一个对应的 JobDetail。
5)JobStore(任务存储):JobStore 是 Quartz 的持久化机制,负责将任务和调度相关的信息存储到数据库或其他存储介质中。这样即使应用程序重启或者服务器关闭,已经配置的调度任务仍然可以得到保留。
6)Listener(监听器):Quartz 提供了丰富的监听器接口,让您可以监控任务的状态变化、执行情况以及异常事件。通过实现 Quartz 的监听器接口,您可以在任务执行前后、暂停和恢复、出现错误等情况下执行额外的逻辑。
7)ThreadPool(线程池):Scheduler 使用线程池来并发执行任务,提高任务的处理效率。Quartz 允许您配置线程池的大小、类型和特性,以适应不同的负载情况。

三大核心组件:
1)任务Job:即想要调用的任务类,需要实现org.quartz.job接口,并重写execute()方法,任务调度时会执行execute()方法。(最新版本实现QuartzJobBean类,重写executeInternal方法)
2)触发器Trigger:即执行任务的触发器,当满足什么条件时会去执行你的任务Job,主要分为根据时长间隔执行的SimpleTrigger和根据日历执行的CronTrigger。
3)调度器Scheduler:即将Trigger和Job绑定之后,根据Trigger中的设定,负责进行Job调度的组件。

五、Quartz持久化

1、为什么要持久化?

当程序突然被中断时,如断电,内存超出时,很有可能造成任务的丢失。可以将调度信息存储到数据库里面,进行持久化,当程序被中断后,再次启动,仍然会保留中断之前的数据,继续执行,而并不是重新开始。

2、Quartz提供了两种持久化方式

Quartz提供两种基本作业存储类型:

1)RAMJobStore
在默认情况下Quartz将任务调度的运行信息保存在内存中,这种方法提供了最佳的性能,因为内存中数据访问最快。不足之处是缺乏数据的持久性,当程序路途停止或系统崩溃时,所有运行的信息都会丢失。

2)JobStoreTX (分布式方式一般采用此种方式,持久化到数据库中)
所有的任务信息都会保存到数据库中,可以控制事物,还有就是如果应用服务器关闭或者重启,任务信息都不会丢失,并且可以恢复因服务器关闭或者重启而导致执行失败的任务。

六、Quartz单实例的入门(大致流程,详细细节可以查看官网)

1、引入pom

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

2、定义Job

只需要继承QuartzJobBean,并重载executeInternal方法即可定义你自己的Job执行逻辑

@Slf4j
public class HelloJob extends QuartzJobBean {

    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        // get parameters
        context.getJobDetail().getJobDataMap().forEach(
                (k, v) -> log.info("param, key:{}, value:{}", k, v)
        );
        // your logics
        log.info("Hello Job执行时间: " + new Date());
    }
}

3、配置Job

JobDetail, Trigger, Schedule(这里采用CronScheduleBuilder)

/**
 * @author pdai
 */
@Configuration
public class QuartzConfig {

    @Bean("helloJob")
    public JobDetail helloJobDetail() {
        return JobBuilder.newJob(HelloJob.class)
                .withIdentity("DateTimeJob")
                .usingJobData("msg", "Hello Quartz")
                .storeDurably()//即使没有Trigger关联时,也不需要删除该JobDetail
                .build();
    }

    @Bean
    public Trigger printTimeJobTrigger() {
        // 每秒执行一次
        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/1 * * * * ?");
        return TriggerBuilder.newTrigger()
                .forJob(helloJobDetail())
                .withIdentity("quartzTaskService")
                .withSchedule(cronScheduleBuilder)
                .build();
    }
}

4、测试定时任务

ps:Quartz分布式案例进入下方借鉴文章查看

七、开源引擎框架与业务如何结合使用

总结:
常见引擎框架:定时任务引擎quartz、规则引擎drools、流程引擎acitiviti等与业务结合的时候,需要在指定的步骤中对业务表进行操作,就可以实现将所需要的信息存入到业务表中,后续把相应的业务表信息与引擎表信息关联就可。例如下方是定时任务执行的类(需要继承QuartzJobBean),此类中就可以进行业务的操作。

/**
 * @date 2023/7/11
 * 定时任务实现类
 */
@Slf4j
public class DataHandler extends QuartzJobBean {

    @Autowired
    private IDataLogService dataLogService;


    // 定时任务执行的类
    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        // 1、context对象可以获取任务id等信息
        // 2、业务操作(比如操作业务表,进行采集任务后,再次更新业务表的采集状态)
        dataLogService.update();
        ...
    }
}

借鉴文章(包含Springboot集成Quartz分布式案例)
借鉴文章(W3Cschool)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

定时任务之Springboot整合Quartz详解 的相关文章

  • 在 Java 中克隆对象 [3 个问题]

    这样做会调用Asub的clone方法吗 或者Asub深度克隆是否正确 如果没有的话 有没有办法通过这种方法对Asub进行深度克隆呢 abstract class Top extends TopMost protected Object cl
  • 不同帐户上的 Spring Boot、JmsListener 和 SQS 队列

    我正在尝试开发一个 Spring Boot 1 5 应用程序 该应用程序需要侦听来自两个不同 AWS 帐户的 SQS 队列 是否可以使用 JmsListener 注解创建监听器 我已检查权限是否正确 我可以使用 getQueueUrl 获取
  • 如何通过 javaconfig 使用 SchedulerFactoryBean.schedulerContextAsMap

    我使用 Spring 4 0 并将项目从 xml 移至 java config 除了访问 Service scheduleService 带注释的类来自QuartzJobBean executeInternal 我必须让它工作的 xml 位
  • 在内存中使用 byte[] 创建 zip 文件。 Zip 文件总是损坏

    我创建的 zip 文件有问题 我正在使用 Java 7 我尝试从字节数组创建一个 zip 文件 其中包含两个或多个 Excel 文件 应用程序始终完成 没有任何异常 所以 我以为一切都好 当我尝试打开 zip 文件后 Windows 7 出
  • Java 枚举与创建位掩码和检查权限的混淆

    我想将此 c 权限模块移植到 java 但是当我无法将数值保存在数据库中然后将其转换为枚举表示形式时 我很困惑如何执行此操作 在 C 中 我创建一个如下所示的枚举 public enum ArticlePermission CanRead
  • 为 java 游戏创建交互式 GUI

    大家好 我正在创建一个类似于 java 中的 farmville 的游戏 我只是想知道如何实现用户通常单击以与游戏客户端交互的交互式对象 按钮 我不想使用 swing 库 通用 Windows 看起来像对象 我想为我的按钮导入自定义图像 并
  • 动态选择端口号?

    在 Java 中 我需要获取端口号以在同一程序的多个实例之间进行通信 现在 我可以简单地选择一些固定的数字并使用它 但我想知道是否有一种方法可以动态选择端口号 这样我就不必打扰我的用户设置端口号 这是我的一个想法 其工作原理如下 有一个固定
  • 如何在java中将一个数组列表替换为另一个不同大小的数组列表

    我有两个大小不同的数组列表 如何从此替换 ArrayList
  • 如何更改javaFX中按钮的图像?

    我正在使用javaFX 我制作了一个按钮并为此设置了图像 代码是 Image playI new Image file c Users Farhad Desktop icons play2 jpg ImageView iv1 new Ima
  • Java 公历日历更改时区

    我正在尝试设置 HOUR OF DAY 字段并更改 GregorianCalendar 日期对象的时区 GregorianCalendar date new GregorianCalendar TimeZone getTimeZone GM
  • java.lang.IllegalStateException:应用程序 PagerAdapter 更改了适配器的内容,而没有调用 PagerAdapter#notifyDataSetChanged android

    我正在尝试使用静态类将值传递给视图 而不是使用意图 因为我必须传递大量数据 有时我会收到此错误 但无法找出主要原因是什么 Error java lang IllegalStateException The application s Pag
  • Java 集合的并集或交集

    建立并集或交集的最简单方法是什么Set在 Java 中 我见过这个简单问题的一些奇怪的解决方案 例如手动迭代这两个集合 最简单的单行解决方案是这样的 set1 addAll set2 Union set1 retainAll set2 In
  • 将流转换为 IntStream

    我有一种感觉 我在这里错过了一些东西 我发现自己做了以下事情 private static int getHighestValue Map
  • jdbc mysql loginTimeout 不起作用

    有人可以解释一下为什么下面的程序在 3 秒后超时 因为我将其设置为在 3 秒后超时 12秒 我特意关闭了mysql服务器来测试mysql服务器无法访问的这种场景 import java sql Connection import java
  • 当 OnFocusChangeListener 应用于包装的 EditText 时,TextInputLayout 没有动画

    不能比标题说得更清楚了 我有一个由文本输入布局包裹的 EditText 我试图在 EditText 失去焦点时触发一个事件 但是 一旦应用了事件侦听器 TextInputLayout 就不再对文本进行动画处理 它只是位于 editText
  • 获取文件的总大小(以字节为单位)[重复]

    这个问题在这里已经有答案了 可能的重复 java 高效获取文件大小 https stackoverflow com questions 116574 java get file size efficiently 我有一个名为 filenam
  • 使用 AsyncTask 传递值

    我一直在努力解决这个问题 但我已经到了不知道该怎么办的地步 我想做的是使用一个类下载文件并将其解析为字符串 然后将该字符串发送到另一个类来解析 JSON 内容 所有部件都可以单独工作 并且我已经单独测试了所有部件 我只是不知道如何将值发送到
  • Opencv Java 灰度

    我编写了以下程序 尝试从彩色转换为灰度 Mat newImage Imgcodecs imread q1 jpg Mat image new Mat new Size newImage cols newImage rows CvType C
  • CamcorderProfile.videoCodec 返回错误值

    根据docs https developer android com reference android media CamcorderProfile html 您可以使用CamcorderProfile获取设备默认视频编解码格式 然后将其
  • 如果没有抽象成员,基类是否应该标记为抽象?

    如果一个类没有抽象成员 可以将其标记为抽象吗 即使没有实际理由直接实例化它 除了单元测试 是的 将不应该实例化的基类显式标记为抽象是合理且有益的 即使在没有抽象方法的情况下也是如此 它强制执行通用准则来使非叶类抽象 它阻止其他程序员创建该类

随机推荐

  • C++中void和void*指针的含义

    转载 http blog chinaunix net uid 22197900 id 359211 html 转载 http www jb51 net article 36570 htm 对以上两篇文章 我进行了重新地汇总整理 转载请注明
  • 电脑系统提示vcomp100.dll文件缺失该怎么办?提示vcomp100.dll丢失问题怎么解决?

    vcomp100 dll实际上是VC 运行库中的一个动态链接库文件 版本是VC 2010 VC2010 Microsoft Visual C 2010 Redistributable Package 安装 Visual C vc2010 库
  • SSH 免密码登录ssh-keygen&ssh-copy-id&sshpass命令详解

    SSH 免密码登录ssh keygen ssh copy id sshpass命令详解 ssh keygen命令详解 功能 生成ssh密钥验证所需要的私钥与公钥文件 参数 t 指定密钥类型 f 指定生成私钥文件名 P 提供 旧 密语 例子
  • 深度学习笔记 4 过拟合+欠拟合+解决方案

    目录 1 偏差与方差 2 产生原因 3 解决欠拟合 高偏差 的方法 3 1 模型复杂化 3 2 增加更多的特征 3 3 调整参数和超参数 3 4 增加训练数据 效果不明显 3 5 降低正则化约束 4 解决过拟合 高方差 的方法 4 1 增加
  • 实例:vmem_disk设备驱动的block_device_operations(3)

    vmem disk提供block device operations结构体中的getgeo 成员函数 如下给出了vmem disk设备驱动的block device operations结构体定义及其成员函数的实现 static int v
  • openwrt中br-lan,eth0,eth0.1,eth0.2 已经 实际网口wan,lan对应的配置

    openwrt的接口真是多 老高一下子都看晕了 不过仔细理一理 还是能够分辨的 首先盗openwrt wiki中的一张图 这张图对理解这些接口很重要 I 网络配置 有线网配置 openwrt的有线网络配置文件位于 etc config ne
  • mybatis5-分页插件.md

    一 jar包 逆向工程不支持分页 PageHelper 底层使用拦截器 二 配置拦截器
  • 小程序大屏适配指南

    小程序大屏适配指南 概述 为保证用户在PC端使用小程序也有流畅友好的体验 本指引将提供一系列大屏适配相关建议 以供参考 1 为什么要做适配 由于用户可在PC端使用小程序 且有可能在不同尺寸视图下进行切换 为了保证小程序在不同尺寸屏幕下的体验
  • ATF(TF-A) fvp_r 平台威胁模型-安全检测与评估

    安全之安全 security 博客目录导读 ATF TF A 威胁模型汇总 目录 一 简介 二 评估目标 1 只支持BL1 2 EL3是不支持的 并且是完全安全的 3 用MPU代替MMU 4 不支持AArch32 5 威胁评估 一 简介 本
  • 什么是模块化?模块化的好处?

    什么是模块化 模块化就是将js文件按照功能分离 根据需求引入不同的文件中 源于服务器端 模块化好处 1 解耦 对业务进行模块化拆分后 为了使各业务模块间解耦 因此各个都是独立的模块 它们之间是没有依赖关系 2 复用 每个模块负责的功能不同
  • Element UI更改下拉菜单el-dropdown-menu样式

    Element UI更改下拉菜单el dropdown menu样式 源代码
  • [网络安全自学篇] 八十一.WHUCTF之WEB类解题思路WP(文件上传漏洞、冰蝎蚁剑、反序列化phar)

    这是作者网络安全自学教程系列 主要是关于安全工具和实践操作的在线笔记 特分享出来与博友们学习 希望您喜欢 一起进步 前文分享了WHUCTF部分题目 包括代码审计 文件包含 过滤绕过 SQL注入 这篇文章将讲解Easy unserialize
  • 接口文档生成工具ApiPost挺好用

    作为一名程序员我深知一款好用的软件工具对工作效率的提升意味着什么 相信不少程序员还在依靠老外们做的软件处理手头工作 曾经我也是其中一员 不过现在我已经开始迷上了国产软件 国外的自然后他的优势 但国产软件工具也吸引了不少程序员开始尝试 虽然他
  • tensorflow2学习笔记

    目录 Tensorflow2 0特性 构架 TensorflowDemo AlexNet 过拟合 卷积后矩阵尺寸大小的计算 代码地址 VGG 感受野 网络结构 代码地址 GoogLeNet GoogLeNet网络结构 参数 Inceptio
  • [机器学习笔记-3]识别服饰图像的神经网络

    目录 1 安装tensorflow数据集 命令行输入 导入依赖 2 导入Fasion MINST数据集 3 处理数据 4 构建模型 5 训练模型 6 评估准确度 7 预测数据 8 图表显示数据 jupyter notebook中运行注意事项
  • 2020年最新的PHP面试题(附答案)

    684 PHP究竟是不是最好的语言 一直以来是程序员最大的 争议 但毋庸置疑的是 PHP绝对是最有前途和力量的变成语言 也是你入门最值得学习的语言 为什么这么说呢 不妨来了解一下 为什么学PHP 语言入门简单 容易掌握 程序建设性好 开发者
  • javaWeb的项目路径问题(对servlet路径和form表单请求路径的一些归纳)

    javaWeb项目的路径问题 这篇文章大神将路径问题讲的很透彻 我想说的是几点小细节 博主说的很清楚 如果这里的deployment下面的application context中不单单仅是一个 后面加的有其他字符的话 在form表单中我们填
  • 深聊测开领域之:Testcase中资源泄露

    1 引言 2 何为资源泄露 2 1 资源泄露定义 2 2 TestCase 中资源泄露 3 避免资源泄露 3 1 如何避免资源泄露 3 2 自动化执行顺序 1 引言 执行测试时离不开测试用例 测试用例辅佐执行测试 这就好比皇帝与宰相 需要的
  • jekyll网站上传服务器,jekyll 高效搭建个人博客之完整流程

    jekyll png 原创精选来自我的博客文章 目录 说在前面的话 作为一个和电脑 代码打交道的我 一直都想拥有自己的博客 一切都显得那么高 zhuang 大 bi 上 yong 在下定决心之后就在网上到处查找资料 最终发现一般用的就三种
  • 定时任务之Springboot整合Quartz详解

    文章目录 一 什么是Quartz 二 为什么使用Quartz 1 为什么要用定时任务 2 为什么使用Quartz 三 常见开源定时任务的框架的异同 四 Quartz的组件 五 Quartz持久化 1 为什么要持久化 2 Quartz提供了两