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

news/2025/1/7 15:00:33/

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.ppmy.cn/news/1560987.html

相关文章

计算机毕业设计Python电商品推荐系统 商品比价系统 电商比价系统 商品可视化 商品爬虫 机器学习 深度学习 京东爬虫 国美爬虫 淘宝爬虫 大数据

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

使用python将多个Excel表合并成一个表

import pandas as pd# 定义要合并的Excel文件路径和名称 file_paths [file1.xlsx, file2.xlsx, file3.xlsx, file4.xlsx, file5.xlsx]# 创建一个空的DataFrame来存储合并后的数据 merged_data pd.DataFrame()# 循环遍历每个Excel文件&#xff0c;并读取其中的数据 for file_p…

HTML基础入门:结构、文本格式化与多媒体图片

HTML基础入门&#xff1a;结构、文本格式化与多媒体图片 HTML&#xff08;超文本标记语言&#xff09;是构建网页的基础语言&#xff0c;是每一位前端开发者的必修课。 HTML文档基本结构 HTML文档的组成 HTML文档的结构就像建筑的框架&#xff0c;支撑起整个网页内容。一个标…

vulnhub——Earth靶机

使用命令在kali查看靶机ip arp-scan -l 第一 信息收集 使用 nmap 进行 dns 解析 把这两条解析添加到hosts文件中去&#xff0c;这样我们才可以访问页面 这样网站就可以正常打开 扫描ip时候我们发现443是打开的&#xff0c;扫描第二个dns解析的443端口能扫描出来一个 txt 文件…

多模态大模型文生图和图生文的主要技术

1 图生文 CLIP 该模型架构由图像编码器和文本编码器组成。图像编码器将图像转换为嵌入&#xff08;数字列表&#xff09;&#xff0c;文本编码器将文本转换为嵌入。 这两个编码器在成批的图像-文本对上进行训练&#xff0c;其中文本描述图像。编码器的训练方式如下&#xff1…

SpringBoot中实现拦截器和过滤器

【SpringBoot中实现过滤器和拦截器】 1.过滤器和拦截器简述 过滤器Filter和拦截器Interceptor&#xff0c;在功能方面很类似&#xff0c;但在具体实现方面差距还是比较大的。 2.过滤器的配置 2.1 自定义过滤器&#xff0c;实现Filter接口(SpringBoot 3.0 开始&#xff0c;jak…

每天学一点强化学习(二)

《动手学强化学习》模仿学习代码的修改 由于版本的不同&#xff0c;模仿学习中的代码需要有一些做出修改&#xff0c; def test_agent(agent, env, n_episode):return_list []for episode in range(n_episode):episode_return 0state env.reset()[0] # 修改位置done False…

向量的导数

向量的导数 向量的导数取决于你对向量的上下文和所涉及的变量维度。常见情况下&#xff0c;我们主要讨论以下两种情况&#xff1a; 1. 标量函数对向量的导数 如果一个标量函数 f ( x ) f(\mathbf{x}) f(x) 是关于向量 x [ x 1 , x 2 , … , x n ] ⊤ \mathbf{x} [x_1, x…