Spring Boot + Quartz 定时任务实战

164 阅读4分钟

掌握 Spring Boot 与 Quartz 搭建定时任务 在实际的项目开发中,定时任务是一个非常常见的需求。Spring Boot 作为一个快速开发框架,结合 Quartz 这个强大的任务调度库,可以轻松实现各种定时任务。下面我们就来详细介绍 Spring Boot + Quartz 定时任务的实战应用。 Quartz 简介 Quartz 是一个功能强大的开源任务调度框架,由 Java 编写,它可以与任何 Java 应用程序集成。Quartz 提供了丰富的 API,允许开发者创建简单或复杂的任务调度。它支持任务的持久化、集群化,并且可以根据时间间隔、日期、日历等多种方式进行任务调度。 举个例子,在电商系统中,我们可能需要定时清理过期的购物车数据,或者每天凌晨生成销售报表。这些任务都可以通过 Quartz 来实现。Quartz 的核心组件包括 Job、Trigger 和 Scheduler。Job 是执行的任务,Trigger 是任务触发的条件,Scheduler 则负责管理和调度任务。 Spring Boot 集成 Quartz 首先,我们需要在 Spring Boot 项目中添加 Quartz 的依赖。在 Maven 项目的 pom.xml 文件中添加以下依赖:

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

添加依赖后,我们就可以开始配置 Quartz。创建一个配置类,用于配置 SchedulerFactoryBean。以下是一个简单的配置示例:

  import org.quartz.Scheduler;
  import org.quartz.SchedulerException;
  import org.quartz.impl.StdSchedulerFactory;
  import org.springframework.context.annotation.Bean;
  import org.springframework.context.annotation.Configuration;

  @Configuration
  public class QuartzConfig {
      @Bean
      public Scheduler scheduler() throws SchedulerException {
          return StdSchedulerFactory.getDefaultScheduler();
      }
  }

通过以上配置,我们成功集成了 Quartz 到 Spring Boot 项目中。 创建定时任务 接下来,我们创建一个简单的定时任务。首先,创建一个 Job 类,实现 org.quartz.Job 接口。以下是一个示例:

  import org.quartz.Job;
  import org.quartz.JobExecutionContext;
  import org.quartz.JobExecutionException;

  public class MyJob implements Job {
      @Override
      public void execute(JobExecutionContext context) throws JobExecutionException {
          System.out.println("定时任务执行:" + System.currentTimeMillis());
      }
  }

在这个示例中,我们创建了一个简单的 Job 类,当任务执行时,会打印当前的时间戳。 然后,我们需要创建一个 Trigger 来触发这个任务。以下是一个使用 www.ysdslt.com/CronTrigger 的示例:

  import org.quartz.*;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.stereotype.Component;

  import javax.annotation.PostConstruct;

  @Component
  public class JobScheduler {
      @Autowired
      private Scheduler scheduler;

      @PostConstruct
      public void scheduleJob() throws SchedulerException {
          JobDetail jobDetail = JobBuilder.newJob(MyJob.class)
                  .withIdentity("myJob", "group1")
                  .build();

          Trigger trigger = TriggerBuilder.newTrigger()
                  .withIdentity("myTrigger", "group1")
                  .withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))
                  .build();

          scheduler.scheduleJob(jobDetail, trigger);
          scheduler.start();
      }
  }

在这个示例中,我们使用 Cron 表达式 "0/5 * * * * ?" 来定义任务每 5 秒执行一次。通过 JobBuilder 创建 JobDetail,通过 TriggerBuilder 创建 Trigger,最后将它们注册到 Scheduler 中并启动。 任务持久化 在实际应用中,我们可能需要将任务信息持久化到数据库中,以便在系统重启后能够恢复任务。Quartz 支持多种数据库,如 MySQL、Oracle 等。 首先,我们需要在 pom.xml 中添加数据库驱动依赖。以 MySQL 为例,添加以下依赖:

  <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
  </dependency>

然后,在 application.properties 中配置数据库连接信息:

  spring.datasource.url=jdbc:mysql://localhost:3306/quartz_db
  spring.datasource.username=root
  spring.datasource.password=123456
  spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

接着,我们需要配置 Quartz 使用数据库持久化。在 QuartzConfig 类中添加以下配置:

  import org.quartz.Scheduler;
  import org.quartz.SchedulerException;
  import org.quartz.impl.StdSchedulerFactory;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.context.annotation.Bean;
  import org.springframework.context.annotation.Configuration;
  import org.springframework.core.io.ClassPathResource;
  import org.springframework.scheduling.quartz.SchedulerFactoryBean;

  import javax.sql.DataSource;
  import java.io.IOException;

  @Configuration
  public class QuartzConfig {
      @Autowired
      private DataSource dataSource;

      @Bean
      public SchedulerFactoryBean schedulerFactoryBean() throws IOException, SchedulerException {
          SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
          schedulerFactoryBean.setDataSource(dataSource);
          schedulerFactoryBean.setConfigLocation(new ClassPathResource("quartz.properties"));
          return schedulerFactoryBean;
      }

      @Bean
      public Scheduler scheduler() throws IOException, SchedulerException {
          return schedulerFactoryBean().getScheduler();
      }
  }

同时,在 resources 目录下创建 quartz.properties 文件,配置 Quartz 的数据库相关信息:

  org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
  org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
  org.quartz.jobStore.dataSource = myDS
  org.quartz.jobStore.tablePrefix = QRTZ_
  org.quartz.dataSource.myDS.driver = com.mysql.cj.jdbc.Driver
  org.quartz.dataSource.myDS.URL = jdbc:mysql://localhost:3306/quartz_db
  org.quartz.dataSource.myDS.user = root
  org.quartz.dataSource.myDS.password = 123456
  org.quartz.dataSource.myDS.maxConnections = 5

通过以上配置,Quartz 会将任务信息存储到数据库中,实现任务的持久化。 集群配置 在高并发场景下,为了保证系统的高可用性和稳定性,我们可以使用 Quartz 的集群功能。Quartz 集群通过数据库来协调多个节点之间的任务调度。 要配置 Quartz 集群,首先需要在 quartz.properties 中添加以下配置:

  org.quartz.jobStore.isClustered = true
  org.quartz.jobStore.clusterCheckinInterval = 20000

在这个配置中,将 isClustered 设置为 true 表示开启集群模式,clusterCheckinInterval 表示节点之间的检查间隔。 然后,在多个节点上部署相同的应用程序,并连接到同一个数据库。这样,Quartz 会自动协调各个节点之间的任务调度,确保任务在集群中均匀分布。 例如,在一个分布式电商系统中,我们可以在多个服务器上部署定时任务,通过 Quartz 集群来保证任务的高可用性。当一个节点出现故障时,其他节点可以继续执行任务。