三种定时任务总结

前言

springboot中设置定时任务有三种常见的方式,分别为:

  1. 基于@Scheduled注解。
  2. 基于Quartz框架。
  3. 基于xxl-job框架。

下面将分别阐述下这三种方式的实现方式和优缺点。

1. @Scheduled

介绍

@Scheduled注解是Spring Framework提供的一个非常简单的创建定时任务的方法,将注解添加在方法。Spring Boot会自动配置一个任务调度器来执行这些方法。

但需要在Spring Boot应用的主类或配置类上添加@EnableScheduling注解来启用定时任务的自动配置。然后,你可以在任何Spring管理的bean上使用@Scheduled注解来声明定时任务。

代码实现
java 复制代码
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class ScheduledTasks {

    @Scheduled(fixedRate = 5000)
    public void taskWithFixedRate() {
        // 任务逻辑
    }

    @Scheduled(cron = "0 * * * * ?")
    public void taskWithCronExpression() {
        // 任务逻辑
    }
}

@Scheduled(fixedRate = 5000)是taskWithFixedRate()方法每5秒执行一次。

@Scheduled(cron = "0 * * * * ?")是taskWithCronExpression()方法根据cron表达式执行。

优点
  • 简单易用 : 只需在方法上添加@Scheduled注解即可,无需复杂配置。
  • 无需额外依赖: Spring框架内置支持,不需要添加额外的库。
  • 集成度高: 与Spring生态系统无缝集成,易于与其他Spring组件协作。
缺点
  • 功能有限:不支持持久化存储任务状态,不适合复杂的调度需求。
  • 不支持分布式: 无法在多个服务实例之间同步任务状态,不适合分布式系统。
  • 缺乏动态控制: 任务调度一旦设定,无法在运行时动态修改(除非重新部署应用)。

2. 基于Quartz框架

介绍

Quartz是一个开源的作业调度库,可以集成到几乎任何Java应用程序中。它提供了丰富的调度选项,包括一次性执行、按照固定间隔重复执行以及基于日历的作业调度。

代码实现
导入依赖
xml 复制代码
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-quartz</artifactId>
                <version>${spring.version}</version>
            </dependency>
写任务逻辑
java 复制代码
package com.account.job;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.stereotype.Component;

/**
 * @author Hao
 * @date 2023-11-06 17:00
 */
@Component
public class UsernameJob implements Job {

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        // 任务逻辑
    }
}
配置定时器
java 复制代码
package com.account.config;

import com.account.job.UsernameJob;
import org.quartz.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author Hao
 * @date 2023-11-06 14:58
 */
@Configuration
public class UsernameQuartzConfig {
    @Bean
    public JobDetail userLogJob() {
        return JobBuilder.newJob(UsernameJob.class)
                .storeDurably(true)
                .build();
    }

    @Bean
    public Trigger usernameJobTrigger() {
        return TriggerBuilder.newTrigger()
                .forJob(userLogJob())
                .withSchedule(CronScheduleBuilder.cronSchedule("0 30 * * * ?")) //每30分钟执行一次
                .build();
    }
}
优点
  • 功能强大: 支持复杂的调度需求,如任务持久化、事务管理、错过任务的处理等。
  • 支持分布式: 可以在多个节点上同步任务状态,适合分布式部署。
  • 灵活性: 支持动态添加、修改和删除任务,以及更复杂的cron表达式。
缺点
  • 配置复杂 : 相较于@Scheduled注解,Quartz需要更多的配置工作。
  • 资源消耗: 因为功能强大,Quartz可能会消耗更多的系统资源。
  • 学习曲线: 对于新手来说,Quartz的API和配置可能需要一定的学习时间。

3. 基于xxl-job框架

介绍

xxl-job是一个分布式任务调度平台,其核心设计目标是开发简单、易扩展、分布式的任务调度解决方案。xxl-job在企业级别的分布式任务调度场景中非常受欢迎。

代码实现
搭建linux服务:搭建教程
导入依赖
xml 复制代码
        <xxl-job.version>2.3.1</xxl-job.version>
            <dependency>
                <groupId>com.xuxueli</groupId>
                <artifactId>xxl-job-core</artifactId>
                <version>${xxl-job.version}</version>
            </dependency>
yml配置文件
yml 复制代码
#XXL-job配置
xxl:
  job:
    admin:
      addresses: http://192.168.133.100:9898/xxl-job-admin
    accessToken: default_token
    executor:
      # 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册
      appname: xxl-job-executor-sample
      # 执行器端口号 [选填]:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口;
      port: 9998
配置类
java 复制代码
package com.replication.config;

import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author Hao
 * @date 2023-12-04 11:07
 */
@Configuration
public class XxlJobConfig {
    @Value("${xxl.job.admin.addresses}")
    private String adminAddresses;

    @Value("${xxl.job.accessToken}")
    private String accessToken;

    @Value("${xxl.job.executor.appname}")
    private String appName;

    @Value("${xxl.job.executor.port}")
    private int port;

    @Bean
    public XxlJobSpringExecutor xxlJobSpringExecutor() {
        XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
        xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
        xxlJobSpringExecutor.setAccessToken(accessToken);
        xxlJobSpringExecutor.setAppname(appName);
        xxlJobSpringExecutor.setPort(port);

        return xxlJobSpringExecutor;
    }
}
注解使用
java 复制代码
@XxlJob("helloXxl")
public void xxlJob() {
    log.debug("xxlJob运行,当前时间:{}", LocalDateTime.now());
}
优点
  • 分布式支持: 设计之初就考虑了分布式场景,适合大规模分布式任务调度。
  • 任务管理: 提供了管理界面,可以方便地对任务进行管理和监控。
  • 高可用性: 支持故障转移和集群部署,提高了任务调度的可靠性。
  • 扩展性: 支持自定义任务类型,可以根据需要扩展任务执行逻辑。
缺点
  • 依赖外部服务: 需要部署xxl-job-admin服务来管理任务,增加了系统复杂性。
  • 额外学习 : 需要学习xxl-job的使用和配置,与Spring Boot的集成程度不如@Scheduled注解。
  • 资源消耗: 由于提供了丰富的功能和管理界面,可能会消耗更多的资源。

总结

在选择定时任务框架时,你应该根据你的应用场景和需求来决定。如果你的应用简单,不需要分布式调度和任务持久化,那么@Scheduled注解可能是最简单的选择。如果你需要更复杂的调度功能,或者你的应用是分布式的,那么Quartz或xxl-job可能更适合。xxl-job特别适合于需要集中管理和监控任务的大型分布式系统。

相关推荐
咖啡啡不加糖17 分钟前
RabbitMQ 消息队列:从入门到Spring Boot实战
java·spring boot·rabbitmq
玩代码25 分钟前
Java线程池原理概述
java·开发语言·线程池
NE_STOP28 分钟前
SpringBoot--如何给项目添加配置属性及读取属性
java
水果里面有苹果30 分钟前
20-C#构造函数--虚方法
java·前端·c#
%d%d233 分钟前
python 在运行时没有加载修改后的版本
java·服务器·python
金銀銅鐵39 分钟前
[Kotlin] 单例对象是如何实现的?
java·kotlin
泰勒疯狂展开40 分钟前
Java研学-MongoDB(三)
java·开发语言·mongodb
zzywxc7871 小时前
AI技术通过提示词工程(Prompt Engineering)正在深度重塑职场生态和行业格局,这种变革不仅体现在效率提升,更在重构人机协作模式。
java·大数据·开发语言·人工智能·spring·重构·prompt
张先shen1 小时前
Elasticsearch RESTful API入门:索引的增删改查完全指南
java·大数据·elasticsearch·搜索引擎·架构·全文检索·restful
天天摸鱼的java工程师1 小时前
工作八年,如果现在让我重做“教务系统”毕业设计,我会这样答...
java·后端