JAVA:Spring Boot 集成 Quartz 实现分布式任务的技术指南

1、简述

Quartz 是一个强大的任务调度框架,允许开发者在应用程序中定义和执行定时任务。在 Spring Boot 中集成 Quartz,可以轻松实现任务的调度、管理、暂停和恢复等功能。在分布式系统中,Quartz 也支持集群化的任务调度,确保任务的高可用性和一致性。本文将介绍如何在 Spring Boot 中集成 Quartz,并展示分布式任务调度的样例。

在这里插入图片描述

2、添加 Quartz 依赖

Quartz 是一个开源的 Java 定时任务调度框架,它可以帮助我们:

  • 定时执行任务,如定时清理数据、邮件通知等。
  • 在复杂的时间规则下灵活调度任务。
  • 支持持久化调度,任务状态可以存储在数据库中,支持任务的恢复与重启。
  • 在分布式环境下,可以实现任务的集群调度。

在这里插入图片描述

在 Spring Boot 中集成 Quartz,首先需要在 pom.xml 中引入 Quartz 的依赖:

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

这个依赖包含了 Spring Boot 对 Quartz 的自动配置支持,帮助我们快速实现定时任务调度。

3、配置 Quartz

在 Spring Boot 项目中,可以通过配置文件来设置 Quartz 的相关属性。这里是一个简单的 Quartz 配置示例:

spring:quartz:job-store-type: jdbc  # 使用 JDBC 存储任务jdbc:initialize-schema: always  # 自动初始化数据库表properties:org:quartz:scheduler:instanceName: MyClusteredSchedulerinstanceId: AUTO  # 自动生成实例IDthreadPool:threadCount: 10  # 调度线程数jobStore:isClustered: true  # 启用集群clusterCheckinInterval: 20000  # 集群节点检查间隔driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate  # 数据库操作类
  • job-store-type: jdbc 表示使用 JDBC 方式来持久化任务和触发器,确保在应用重启或宕机后任务能够恢复。
  • isClustered: true 表示启用了 Quartz 集群模式,支持多节点协调任务调度。

4、初始化数据库表

Quartz 使用 JDBC 模式时需要有数据库表来存储任务和触发器。你可以通过执行官方的 SQL 脚本来创建这些表,具体 SQL 脚本可以从 Quartz 官方 GitHub 获取。

对于 MySQL 数据库,可以在项目中执行 quartz_tables_mysql.sql:

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)
);
-- 其他表略

5、定义 Quartz Job 和触发器

在 Quartz 中,任务(Job)是调度的最小单位,触发器(Trigger)决定了任务何时执行。我们首先需要定义一个简单的 Job,例如一个打印日志的任务:

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public class SimpleJob implements Job {private static final Logger logger = LoggerFactory.getLogger(SimpleJob.class);@Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {logger.info("执行定时任务:SimpleJob - {}", System.currentTimeMillis());}
}

接下来,为这个任务创建一个触发器。在 Spring 中,我们可以使用 JobDetail 和 Trigger 来定义:

import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class QuartzConfig {@Beanpublic JobDetail simpleJobDetail() {return JobBuilder.newJob(SimpleJob.class).withIdentity("simpleJob").storeDurably()  // 即使没有触发器关联时,也保留该任务.build();}@Beanpublic Trigger simpleJobTrigger() {return TriggerBuilder.newTrigger().forJob(simpleJobDetail()).withIdentity("simpleTrigger").withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(10)  // 每10秒执行一次.repeatForever()).build();}
}

在这个配置中,JobDetail 定义了 SimpleJob 的细节,Trigger 定义了任务每 10 秒执行一次。

6、Quartz 集群的配置

为了在分布式环境中实现 Quartz 的集群调度,除了上述的 JDBC 持久化配置外,还需要在不同的节点上配置相同的数据库和 Quartz 配置。这些节点可以同时运行,当一个节点失效时,另一个节点将接管其任务。Quartz 通过数据库锁来确保任务只在一个节点上执行。

在每个节点上,只需确保:

  • 使用相同的 Quartz 数据库配置。
  • 保持 isClustered: true。
  • 配置唯一的 instanceId(可以使用 AUTO 自动生成)。

假设我们有两个微服务实例,它们共同调度同一个任务。在这两个实例上,只需要共享同一个数据库,同时启用集群模式:

spring:quartz:job-store-type: jdbcjdbc:initialize-schema: never  # 数据库表已经在某个节点初始化properties:org:quartz:scheduler:instanceName: ClusteredSchedulerNode1  # 每个节点需要唯一的实例名称instanceId: AUTOjobStore:isClustered: trueclusterCheckinInterval: 20000

启动多个服务实例后,Quartz 会自动协调各个节点的任务调度。在某个节点失效时,其他节点会接管其任务,确保任务调度的高可用性。

7、日志与监控

为了更好地了解 Quartz 的运行状态,可以通过日志来监控任务的执行情况。Spring Boot 提供了良好的日志管理机制,开发者可以在 application.yml 中配置日志级别:

logging:level:org.quartz: DEBUG

此外,可以通过集成 Spring Boot Actuator 来监控 Quartz 的运行状态和任务调度情况。

8、总结

通过集成 Quartz,Spring Boot 项目可以轻松实现任务调度功能,并且在分布式环境中支持任务的集群化调度。本文详细介绍了 Quartz 的基本配置、任务调度示例,以及如何在分布式系统中使用 Quartz 实现高可用的任务调度。希望本文能帮助你在项目中顺利使用 Quartz 来管理和调度定时任务。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/502327.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据分析-Excel

数据类型和函数初步 Excel中有文本类型和数值类型–但是无法用肉眼分辨出来isnumber来区分是否是数值类型text和value函数可以完成数值类型以及文本类型的转换单元格第一位输入’方式明确输入的是文本sum函数必须是数值类型 文本连接-and-or-not-if-mod-max函数 字符串的连接…

深入了解 SSL/TLS 协议及其工作原理

深入了解 SSL/TLS 协议及其工作原理 一. 什么是 SSL/TLS?二. SSL/TLS 握手过程三. SSL/TLS 数据加密与传输四. 总结 点个免费的赞和关注&#xff0c;有错误的地方请指出&#xff0c;看个人主页有惊喜。 作者&#xff1a;神的孩子都在歌唱 一. 什么是 SSL/TLS? 安全套接层&am…

【NLP高频面题 - Transformer篇】Transformer的输入中为什么要添加位置编码?

Transformer的输入中为什么要添加位置编码&#xff1f; 重要性&#xff1a;★★★ Transformer 将句子中的所有词并行地输入到神经网络中。并行输入有助于缩短训练时间&#xff0c;同时有利于学习长期依赖。不过&#xff0c;并行地将词送入 Transformer&#xff0c;却不保留词…

【Unity3D】UGUI Canvas画布渲染流程

目录 Screen Space - Overlay Screen Space - Camera World Space UI合批分析&#xff08;建议不看 直接看FrameDebugger测试&#xff09; 优化UI合批 1、Image图片纹理不同导致合批失败 2、文本和图片相交以及排序对合批的影响 参考文档&#xff1a;画布 - Unity 手册…

计算机的错误计算(二百零一)

摘要 用两个大模型计算 &#xff0c;结果保留 10位有效数字。实验表明&#xff0c;两个大模型的输出均只有1位正确数字&#xff1b;并它们几乎相同&#xff1a;仅最后1位数字不同。 例1. 计算 , 结果保留 10位有效数字。 下面是与一个数学解题器的对话。 以上为与一个数学解…

完全分布式部署Hadoop集群

(1)第一步&#xff1a;安装Hadoop&#xff0c;使用如下命令&#xff1a; tar -zvxf /export/software/Hadoop-3.3.4.tar.gz -C /export/servers (2)第二步&#xff1a;配置Hadoop系统环境变量 在liumengting1上执行vi /etc/profile命令配置系统环境变量profile&#xff0c;在…

Redis数据库笔记—— Hash(哈希)的扩容机制(rehash)

大家好&#xff0c;这里是Good Note&#xff0c;关注 公主号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。详细介绍Hash&#xff08;哈希&#xff09;的扩容机制(rehash)、源码、以及扩容和缩容过程。 文章目录 Redis 字典&#xff08;dict&#xff09;结构源码哈希…

使用命令行管理git项目

# 初始化一个新的Git仓库 git init # 添加文件到暂存区 git add <file> # 提交暂存区的更改到仓库 git commit -m "commit message" # 查看当前仓库的状态 git status # 查看提交历史 git log # 查看文件的改动 git diff <file> # 创建一个新…

设计模式 创建型 工厂模式(Factory Pattern)与 常见技术框架应用 解析

工厂模式&#xff08;Factory Pattern&#xff09;是一种创建型设计模式&#xff0c;它提供了一种封装对象创建过程的方式&#xff0c;使得对象的创建与使用分离&#xff0c;从而提高了系统的可扩展性和可维护性。 一、核心思想 工厂模式的核心思想是将“实例化对象”的操作与…

【Block总结】Conv2Former中的Block,卷积调制块,简化了自注意力机制,提高了内存效率

论文介绍 论文链接&#xff1a;https://arxiv.org/pdf/2211.11943 研究背景&#xff1a;论文指出&#xff0c;尽管当前研究者们通过利用大核卷积、高阶空间交互或稀疏卷积核等方法对卷积神经网络&#xff08;ConvNets&#xff09;的设计进行了重新思考&#xff0c;但如何更有…

w139华强北商城二手手机管理系统

&#x1f64a;作者简介&#xff1a;多年一线开发工作经验&#xff0c;原创团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339;赠送计算机毕业设计600个选题excel文…

ThreadPoolExecutor keepAliveTime 含义

现象 在线上环境排查问题时&#xff0c;某个线程池在某个时间点新建线程达到设定的最大线程数 maximumPoolSize&#xff0c;后续流量降低后当前线程数仍未回落&#xff0c;仍然为最大线程数&#xff0c;阻塞队列中有任务&#xff0c;但是活跃线程数显著减少。 之前的认知 固…

如何恢复已删除的 Telegram 消息 [iOSamp;Android]

Telegram 是一款功能强大的消息应用程序&#xff0c;因其易用性、隐私保护和众多炫酷功能而深受用户喜爱。然而&#xff0c;有时我们会不小心删除重要的消息。在这种情况下你应该做什么&#xff1f; 本文将为您提供简单有效的解决方案来恢复 Telegram 上已删除的消息&#xff…

Outlook2024版如何回到经典Outlook

Outlook2024版如何回到经典Outlook 如果新加入一家公司&#xff0c;拿到的电脑&#xff0c;大概率是最新版的Windows, 一切都是新的。 如果不coding, 使用国产的foxmail大概就可以解决一切问题了。可惜老程序员很多Coding都是基于传统Outlook的&#xff0c;科技公司所有人都是I…

动态库dll与静态库lib编程4:MFC规则DLL讲解

文章目录 前言一、说明二、具体实现2.1新建项目2.2 模块切换的演示 总结 前言 动态库dll与静态库lib编程4&#xff1a;MFC规则DLL讲解。 一、说明 1.前面介绍的均为Win32DLL&#xff0c;即不使用MFC的DLL。 2.MFC规则DLL的特点&#xff1a;DLL内部可以使用MFC类库、可以被其他…

若依中Feign调用的具体使用(若依微服务版自身已集成openfeign依赖,并在此基础上定义了自己的注解)

若依中Feign调用具体使用 注意&#xff1a;以下所有步骤实现的前提是需要在启动类上加入注解 EnableRyFeignClients 主要是为开启feign接口扫描 1.创建服务提供者(provider) 导入依赖(我在分析依赖时发现若依本身已经引入openfeign依赖,并在此基础上自定义了自己的EnableRyF…

CSS3——3. 书写格式二

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title></title></head><body><!--css书写&#xff1a;--><!--1. 属性名:属性值--><!--2.属性值是对属性的相关描述--><!--3.属性名必须是…

zookeeper 数据类型

文章目录 引言I Znodezonde stat (状态信息)znode类型临时\永久序列化特性引言 在结构上与标准文件系统非常类似,拥有一个层次的命名空间,都是采用树形层次结构 Zookeeper树中的每个节点被称为:Znode,没有文件和目录之分。Znode兼具文件和目录两种特点Znode存储数据大小有…

Hadoop集群之间实现免密登录

实现虚拟机之间能够互相登录&#xff0c;比如可以在hadoop1上面登录hadoop2。 第一步&#xff1a;执行”ssh-keygen -t rsa”命令&#xff0c;生成该虚拟机的密钥 第二步&#xff1a;密钥文件存储在/root/.ssh目录&#xff0c;执行cd /root/.ssh命令进入存储密钥文件的目录&am…

【linux基础I/O(1)】文件描述符的本质重定向的本质

目录 前言1. 理解C语言的文件接口2. 操作文件的系统调用接口2.1 open函数详解2.2 close函数详解2.3 write函数详解2.4 read函数详解 3. 文件描述符fd详解4. 文件描述符的内核本质5. 怎样理解Linux下一切皆文件?6. 理解输出输入重定向7. 重定向的系统调用8. 总结 前言 “在Lin…