Java中三种定时任务总结(schedule,quartz,xxl-job)

news2024/12/27 0:53:18

目录

1、Spring框架的定时任务

2、Quartz

Quartz的用法

3、xxl-job

3.1 docker 安装xxl-job

3.2 xxl-job编程测试

补充:Java中自带的定时任务调度

1. java.util.Timer和java.util.TimerTask

2. java.util.concurrent.Executors和java.util.concurrent.ScheduledExecutorService

小结


1、Spring框架的定时任务

Spring框架提供了强大的定时任务支持。通过使用@Scheduled注解,可以将一个方法标记为定时任务,并指定任务的执行时间规则。可以设置任务在固定的时间点执行,也可以设置任务在一定的时间间隔内重复执行。Spring的定时任务功能更加灵活,支持各种时间表达式,也可以配置多线程执行任务。

  1. Spring @Scheduled注解:这是一个基于Spring框架的应用程序,并通过Spring提供的@Scheduled注解来非常简便地实现定时任务。只需在方法上添加@Scheduled注解,并指定一个cron表达式,就可以在指定的时间执行该方法。
  2. Spring Boot @Scheduled注解:在Spring Boot框架中,也可以使用@Scheduled注解来创建定时任务。Spring Boot还提供了一个自动配置的Scheduler,使得创建和配置定时任务变得非常简单。

2、Quartz

Quartz是一个由Java编写的开源作业调度框架,它允许与J2EE和J2SE应用程序相结合,也可以单独使用。Quartz可以用来创建简单或复杂的程序,包括运行十个、百个甚至上万个Jobs。这些Jobs可以做成标准的Java组件或EJBs。Quartz支持丰富的调度策略,例如支持多线程、优先级、异常处理等。

详情可见以下地址:

Quartz Enterprise Job Scheduler

java 调度框架 java任务调度框架有哪些_mob64ca140fd7c1的技术博客_51CTO博客

Java任务调度框架Quartz教程-腾讯云开发者社区-腾讯云

Quartz的核心概念包括Job、JobDetail和Trigger等。Job表示一个工作,包含要执行的具体内容,其接口中只有一个方法。JobDetail表示一个具体的可执行的调度程序,包含了这个任务调度的方案和策略。Trigger代表一个调度参数的配置,定义了何时去调度。Scheduler则是代表一个调度容器,一个调度容器中可以注册多个JobDetail和Trigger,当Trigger与JobDetail组合时,就可以被Scheduler容器调度了。

  1. 作业(Job):表示一个要执行的任务或工作单元。根据具体需求,可以自定义实现 org.quartz.Job 接口或继承 org.quartz.InterruptableJob 接口,并实现 execute() 方法来定义任务的执行逻辑。

  2. 任务(Task):是作业的实例,即具体要执行的任务对象。每次作业被触发时,都会创建一个新的任务实例。

  3. 触发器(Trigger):定义作业何时触发执行的条件。Quartz 提供了多种触发器类型,如简单触发器 SimpleTrigger、日历触发器 CalendarTrigger 和 Cron 触发器 CronTrigger 等。通过配置触发器的属性,如触发时间、重复间隔等,可以灵活地定义作业的触发规则。

  4. 调度器(Scheduler):是 Quartz 的核心组件,负责管理和协调作业的调度和执行。调度器可以启动、停止和暂停作业的执行,并根据触发器的配置规则触发作业执行。

  5. 上下文(Context):提供了在作业执行期间访问调度器和其他环境信息的方式。作业实例可以通过上下文对象获取调度器、触发器和其他相关信息。

  6. 监听器(Listener):用于监听作业和触发器的事件,如作业执行前后、触发器触发前后等。通过实现监听器接口,可以在特定事件发生时执行自定义的逻辑。

  7. 任务存储(JobStore):Quartz 使用任务存储来持久化作业和触发器的状态信息,以便在应用重启后能够恢复调度任务。Quartz 提供了多种任务存储实现,包括内存存储、数据库存储和集群存储等。

Quartz的使用非常灵活。比如,可以配置一个Job实现类并设定好调度时间表,Quartz就会密切注意剩余时间,当调度程序确定该是通知作业的时候,Quartz框架就会调用Job实现类(作业类)上的execute()方法并允许做它该做的事情。这个过程无需报告任何东西给调度器或调用任何特定的东西,Quartz会执行任务并结束任务。如果配置作业在随后再次被调用,Quartz框架也将在恰当的时间再次调用它。

Quartz的内部架构大约包含300个Java类和接口,并被组织到12个包中。尽管规模几乎不会用来作为衡量框架质量的一个特性,但这里的关键是quartz内含很多功能,这些功能和特性集是否成为、或者应该成为评判一个开源或非开源框架质量的因素。

Quartz的用法

1. 添加Quartz依赖

首先需要在项目中添加Quartz的依赖。如果你使用Maven,可以在pom.xml文件中添加以下依赖:

<dependency>  
    <groupId>org.quartz-scheduler</groupId>  
    <artifactId>quartz</artifactId>  
    <version>2.3.2</version>  
</dependency>

2. 创建Job类

创建一个简单的Job类,该类实现了Quartz的Job接口,并覆盖了execute方法。在这个例子中,我们将输出“Hello Quartz!”到控制台。

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("Hello Quartz!");  
    }  
}

3. 创建Scheduler类

创建一个Scheduler类,该类负责配置Quartz并启动调度器。在这个例子中,我们将创建一个简单的调度器,并注册一个任务(MyJob)来每5秒钟执行一次。

import org.quartz.*;  
import org.quartz.impl.StdSchedulerFactory;  
import org.quartz.impl.triggers.SimpleTrigger;  
  
public class MyScheduler {  
    public static void main(String[] args) throws SchedulerException {  
        // 创建调度器工厂并获取调度器实例  
        SchedulerFactory schedulerFactory = new StdSchedulerFactory();  
        Scheduler scheduler = schedulerFactory.getScheduler();  
        // 启动调度器  
        scheduler.start();  
        // 创建任务并注册到调度器中,每5秒钟执行一次  
        JobDetail jobDetail = JobBuilder.newJob(MyJob.class)  
                .withIdentity("myJob", "group1")  
                .build();  
        Trigger trigger = TriggerBuilder.newTrigger()  
                .withIdentity("myTrigger", "group1")  
                .withSchedule(SimpleScheduleBuilder.simpleSchedule()  
                        .withIntervalInSeconds(5)  
                        .repeatForever())  
                .build();  
        scheduler.scheduleJob(jobDetail, trigger);  
    }  
}

3、xxl-job

官方网站及文档:

分布式任务调度平台XXL-JOB

GitHub - xuxueli/xxl-job: A distributed task scheduling framework.(分布式任务调度平台XXL-JOB)

xxl-job 是一个分布式任务调度平台,它的核心部分包括以下几个方面:

  1. 调度中心(JobAdmin):负责任务的管理和调度,包括任务的创建、编辑、删除,以及任务的调度策略配置等。调度中心还负责监控任务的执行情况,并提供任务日志查询和报警功能。

  2. 执行器(JobExecutor):负责具体的任务执行。执行器在分布式环境中部署在各个节点上,通过与调度中心进行通信,接收调度中心分配的任务,并执行任务逻辑。执行器还负责任务的报警和日志上报等功能。

  3. 调度模型:xxl-job 提供了多种调度模型,包括固定间隔触发、Cron 表达式触发、API 触发等。用户可以根据自己的需求选择合适的调度模型来触发任务的执行。

  4. 任务路由策略:xxl-job 支持多种任务路由策略,包括轮询、一致性哈希、故障转移等。任务路由策略决定了任务在分布式环境下的执行节点选择方式,保证任务的高可用性和负载均衡。

  5. 监控和报警:xxl-job 提供了丰富的监控指标和报警机制,可以实时监控任务的执行情况,包括任务的成功、失败、运行时间等指标。同时,xxl-job 还支持邮件、短信等方式进行任务执行状态的报警通知。

  6. 可视化管理界面:xxl-job 提供了友好的可视化管理界面,方便用户进行任务的配置和管理,同时也提供了任务执行日志查询、任务执行情况统计等功能。通过强大的调度中心和执行器,提供了可靠的任务调度功能和高效的分布式任务执行能力,帮助用户实现任务的自动化调度和管理。

3.1 docker 安装xxl-job

查询并拉取镜像

查询:docker search xuxueli

选择并拉取该镜像:docker pull xuxueli/xxl-job-admin:2.3.1(可自选版本)

配置docker-compose.yml文件

version: '2'
#自定义的docker网络
networks:
  docker_net:
    external: true
services:
  xxl-job-compose:
    #读取docker-compose/Dockerfile的位置
    build: .
    #镜像名称
    image: xuxueli/xxl-job-admin:2.3.1
    #容器名称
    container_name: xxl-job
    ports:
      - "9898:8080"
    environment:
      PARAMS: '--spring.datasource.url=jdbc:mysql://192.168.***.***:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
               --spring.datasource.username=root
               --spring.datasource.password=123'
    volumes:
      - /usr/local/software/xxl-job/log:/data/applogs
    networks:
      docker_net:
        ipv4_address: 172.18.12.100

加载数据库

后台运行创建xxl-job容器

docker-compose up -d

进入xxl-job网页

3.2 xxl-job编程测试

引入依赖

        <dependency>
            <groupId>com.xuxueli</groupId>
            <artifactId>xxl-job-core</artifactId>
            <version>2.3.1</version>
        </dependency>

配置application.yml文件

server:
  port: 13000
#xxljob的配置
xxl:
  job:
    admin:
      addresses: http://192.168.***.***:9898/xxl-job-admin
    executor:
      appname: xxl-job-executor-sample
      port: 9777
    accessToken: default_token

logging:
  level:
    com.wow: debug

添加Java配置类

package com.wnhz.ssc.job.config;

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


@Slf4j
@Configuration
public class XxlJobConfig {
    @Value("${xxl.job.admin.addresses}")
    private String address;
    @Value("${xxl.job.executor.appname}")
    private String appName;
    @Value("${xxl.job.executor.port}")
    private int port;
    @Value("${xxl.job.accessToken}")
    private String accessToken;

    @Bean
    public XxlJobSpringExecutor xxlJobSpringExecutor(){
        XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
        xxlJobSpringExecutor.setAccessToken(accessToken);
        xxlJobSpringExecutor.setAdminAddresses(address);
        xxlJobSpringExecutor.setAppname(appName);
        xxlJobSpringExecutor.setPort(port);
        log.debug("xxl-job已初始化",xxlJobSpringExecutor);
        return xxlJobSpringExecutor;
    }
}

创建调度任务测试

@Component
@Slf4j
public class MyJobs {
    @XxlJob("helloXxl")
    public void helloXxlJob(){
        log.debug("hello,xxljob");
    }
}

web管理端新建任务

注意:JobHandler需与代码中的调度名称一致!

保存,启动程序测试

控制台查看或者web端查看调度日志


补充:Java中自带的定时任务调度

1. java.util.Timerjava.util.TimerTask

这是Java标准库提供的定时任务工具类。Timer类用于创建定时器,并可以调度TimerTask类的任务执行。通过调用schedule()方法,可以指定任务在未来的某个时间点执行,也可以指定任务在一定的时间间隔内重复执行。

Timer timer = new Timer();  
timer.schedule(new TimerTask() {  
    @Override  
    public void run() {  
        // 需要执行的任务  
    }  
}, 0, 1000);  // 任务延迟0毫秒后开始,每隔1000毫秒执行一次

2. java.util.concurrent.Executorsjava.util.concurrent.ScheduledExecutorService

这是Java并发包提供的定时任务框架,是Java 5及以上版本中提供的一个更强大的定时任务调度器,相比于Timer类,它提供了更灵活的调度策略,例如支持固定延迟、固定速率、周期性调度等。

ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);  
executor.scheduleAtFixedRate(new Runnable() {  
    @Override  
    public void run() {  
        // 需要执行的任务  
    }  
}, 0, 1, TimeUnit.SECONDS);  // 任务延迟0秒后开始,每隔1秒执行一次

ScheduledExecutorService接口继承自ExecutorService接口,可以支持延迟执行和周期性执行任务。通过schedule()方法,可以指定任务在未来的某个时间点执行。通过scheduleAtFixedRate()方法或scheduleWithFixedDelay()方法,可以指定任务在一定的时间间隔内重复执行。

图片来源:【任务调度框架】「分析技术指南」带你一同盘点一下常用的任务调度框架的方案和原理开发指南_任务调度详细介绍-CSDN博客

如果只是简单的定时任务需求,使用java.util.Timerjava.util.TimerTask就足够了;如果需要更强大的定时任务功能,可以选择使用java.util.concurrent.ScheduledExecutorService。


小结

定时任务特点所属类型
Timer (Java Platform SE 8 )定时任务框架,非线程安全,如任务执行时间过长,会影响后续任务的执行。 Java自带
ScheduledExecutorService (Java Platform SE 8 )Java自带的定时任务框架,提供了更多的功能和灵活性,并且是线程安全。 Java自带
Quartz是一个全功能、开源的任务调度服务,可以集成几乎任何的java应用程序—从小的单片机系统到大型的电子商务系统。Quartz可以执行上千上万的任务调度。开源的
Spring TaskSpring框架自带的通过@Scheduled注解使用Spring框架自带
分布式任务调度平台XXL-JOB

XXL-JOB是一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。

分布式

参考

【任务调度框架】「分析技术指南」带你一同盘点一下常用的任务调度框架的方案和原理开发指南_任务调度详细介绍-CSDN博客

java定时任务调度框架 - pluto_charon - 博客园

Java任务调度框架Quartz教程-腾讯云开发者社区-腾讯云

java 调度框架 java任务调度框架有哪些_mob64ca140fd7c1的技术博客_51CTO博客


感谢阅读,码字不易,多谢点赞!如有不当之处,欢迎反馈指出,感谢!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

TI 毫米波雷达器件中的自校准功能(TI文档)

摘要 TI 的毫米波雷达传感器包括一个内部处理器和硬件架构&#xff0c;支持自校准和监控。校准可确保在温度和工艺变化范围内维持雷达前端的性能。监控可以周期性测量射频/模拟性能参数并检测潜在故障。 本应用手册简要介绍了校准和监控机制&#xff0c;主要侧重于内部…

整数的立方和

系列文章目录 进阶的卡莎C++_睡觉觉觉得的博客-CSDN博客数1的个数_睡觉觉觉得的博客-CSDN博客双精度浮点数的输入输出_睡觉觉觉得的博客-CSDN博客足球联赛积分_睡觉觉觉得的博客-CSDN博客大减价(一级)_睡觉觉觉得的博客-CSDN博客小写字母的判断_睡觉觉觉得的博客-CSDN博客纸币(…

卷积神经网络(CNN):乳腺癌识别.ipynb

文章目录 一、前言一、设置GPU二、导入数据1. 导入数据2. 检查数据3. 配置数据集4. 数据可视化 三、构建模型四、编译五、训练模型六、评估模型1. Accuracy与Loss图2. 混淆矩阵3. 各项指标评估 一、前言 我的环境&#xff1a; 语言环境&#xff1a;Python3.6.5编译器&#xf…

线程池、及Springboot线程池实践

摘要 本文介绍了线程池基本概念、线程及线程池状态、java中线程池提交task后执行流程、Executors线程池工具类、最后介绍在springboot框架下使用线程池和定时线程池&#xff0c;以及task取消 线程池基本 背景 线程池 线程池是一种多线程处理形式&#xff0c;处理过程中将任务…

HCIP——交换综合实验

一、实验拓扑图 二、实验需求 1、PC1和PC3所在接口为access&#xff0c;属于vlan2&#xff1b;PC2/4/5/6处于同一网段&#xff0c;其中PC2可以访问PC4/5/6&#xff1b;但PC4可以访问PC5&#xff0c;不能访问PC6 2、PC5不能访问PC6 3、PC1/3与PC2/4/5/6/不在同一网段 4、所有PC通…

【Java】类和对象之超级详细的总结!!!

文章目录 前言1. 什么是面向对象&#xff1f;1.2面向过程和面向对象 2.类的定义和使用2.1什么是类&#xff1f;2.2类的定义格式2.3类的实例化2.3.1什么是实例化2.3.2类和对象的说明 3.this引用3.1为什么会有this3.2this的含义与性质3.3this的特性 4.构造方法4.1构造方法的概念4…

数据结构第六课 -----链式二叉树的实现

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; ​&#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382; &#x1f389;&#x1f389;&#x1f389…

Java生成word[doc格式转docx]

引入依赖 <!-- https://mvnrepository.com/artifact/org.freemarker/freemarker --><dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.32</version></dependency> doc…

针对net core 使用CSRedis 操作redis的三种连接实例方式

1、主从访问 2、哨兵模式 3、集群访问 写法一&#xff1a;写任意一个地址即可&#xff0c;其它节点在运行过程中自动增加&#xff0c;确保每个节点密码一致。如&#xff1a;Console.WriteLine("集群测试");RedisHelper.Initialization(new CSRedis.CSRedisClient(&q…

Http和WebSocket

客户端发送一次http请求&#xff0c;服务器返回一次http响应。 问题&#xff1a;如何在客户端没有发送请求的情况下&#xff0c;返回服务端的响应&#xff0c;网页可以得服务器数据&#xff1f; 1&#xff1a;http定时轮询 客户端定时发送http请求&#xff0c;eg&#…

回溯和分支算法

状态空间图 “图”——状态空间图 例子&#xff1a;农夫过河问题——“图”状态操作例子&#xff1a;n后问题、0-1背包问题、货郎问题(TSP) 用向量表示解&#xff0c;“图”由解向量扩张得到的解空间树。 ——三种图&#xff1a;n叉树、子集树、排序树 ​ 剪枝 不满住条件的…

链表【3】

文章目录 &#x1f433;23. 合并 K 个升序链表&#x1f41f;题目&#x1f42c;算法原理&#x1f420;代码实现 &#x1f437;25. K 个一组翻转链表&#x1f416;题目&#x1f43d;算法原理&#x1f367;代码实现 &#x1f433;23. 合并 K 个升序链表 &#x1f41f;题目 题目链…

Sentinel基础知识

Sentinel基础知识 资源 1、官方网址&#xff1a;https://sentinelguard.io/zh-cn/ 2、os-china: https://www.oschina.net/p/sentinel?hmsraladdin1e1 3、github: https://github.com/alibaba/Sentinel 一、软件简介 Sentinel 是面向分布式服务架构的高可用流量防护组件…

Unity 关于SetParent方法的使用情况

在设置子物体的父物体时&#xff0c;我们使用SetParent再常见不过了。 但是通常我们只是使用其中一个语法&#xff1a; public void SetParent(Transform parent);使用改方法子对象会保持原来位置&#xff0c;跟使用以下方法效果一样&#xff1a; public Transform tran; ga…

【数值计算方法(黄明游)】函数插值与曲线拟合(二):Newton插值【理论到程序】

​ 文章目录 一、近似表达方式1. 插值&#xff08;Interpolation&#xff09;2. 拟合&#xff08;Fitting&#xff09;3. 投影&#xff08;Projection&#xff09; 二、Lagrange插值1. 拉格朗日插值方法2. Lagrange插值公式a. 线性插值&#xff08;n1&#xff09;b. 抛物插值&…

UDS 诊断报文格式

文章目录 网络层目的N_PDU 格式诊断报文的分类&#xff1a;单帧、多帧 网络层目的 N_PDU(network protocol data unit)&#xff0c;即网络层协议数据单元 网络层最重要的目的就是把数据转换成符合标准的单一数据帧&#xff08;符合can总线规范的&#xff09;&#xff0c;从而…

原生横向滚动条 吸附 页面底部

效果图 /** 横向滚动条 吸附 页面底部 */ export class StickyHorizontalScrollBar {constructor(options {}) {const { el, style } optionsthis.createScrollbar(style)this.insertScrollbar(el)this.setScrollbarSize()this.onEvent()}/** 创建滚轴组件元素 */createS…

【踩坑】解决maven的编译报错Cannot connect to the Maven process. Try again later

背景 新公司新项目, 同事拷给我maven的setting配置文件, 跑项目编译发现maven报 Cannot connect to the Maven process. Try again later. If the problem persists, check the Maven Importing JDK settings and restart IntelliJ IDEA 虽然好像不影响, 项目最终还是能跑起来…

计算机组成学习-存储系统总结

复习本章时&#xff0c;思考以下问题&#xff1a; 1)存储器的层次结构主要体现在何处&#xff1f;为何要分这些层次&#xff1f;计算机如何管理这些层次&#xff1f;2)存取周期和存取时间有何区别&#xff1f;3)在虚拟存储器中&#xff0c;页面是设置得大一些好还是设置得小一…