侧边栏壁纸
博主头像
拾荒的小海螺博主等级

只有想不到的,没有做不到的

  • 累计撰写 194 篇文章
  • 累计创建 19 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

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

拾荒的小海螺
2024-10-14 / 0 评论 / 0 点赞 / 15 阅读 / 6626 字

1、简述

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

1728867887344.jpg

2、添加 Quartz 依赖

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

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

1728867904816.jpg

在 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: MyClusteredScheduler
            instanceId: AUTO  # 自动生成实例ID
          threadPool:
            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);

    @Override
    public 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 {

    @Bean
    public JobDetail simpleJobDetail() {
        return JobBuilder.newJob(SimpleJob.class)
                .withIdentity("simpleJob")
                .storeDurably()  // 即使没有触发器关联时,也保留该任务
                .build();
    }

    @Bean
    public 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: jdbc
    jdbc:
      initialize-schema: never  # 数据库表已经在某个节点初始化
    properties:
      org:
        quartz:
          scheduler:
            instanceName: ClusteredSchedulerNode1  # 每个节点需要唯一的实例名称
            instanceId: AUTO
          jobStore:
            isClustered: true
            clusterCheckinInterval: 20000

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

7、日志与监控

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

logging:
  level:
    org.quartz: DEBUG

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

8、总结

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

0

评论区