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

目录

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博客


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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

前端开发_CSS

CSS定义 层叠样式表 (Cascading Style Sheets&#xff0c;缩写为 CSS&#xff09;&#xff0c;是一种 样式表 语言&#xff0c;用来描述 HTML 文档的呈现&#xff08;美化内容&#xff09; 书写位置&#xff1a;title 标签下方添加 style 双标签&#xff0c;style 标签里面书…

Qt应用开发(Quick篇)——矩形模块 Rectangle

一、前言 矩形模块用于用纯色或渐变填充区域&#xff0c;或者提供一个矩形边框。 二、外观 每个矩形项都可以使用使用color属性指定的纯填充色、使用gradient类型定义并使用gradient属性设置的渐变来绘制。如果同时指定了颜色和渐变效果&#xff0c;则只会生效渐变效果。 通过…

探讨Unity中的动画融合技术(BlendTree)

动画在游戏和虚拟现实应用中扮演着关键的角色&#xff0c;而动画融合技术则是使角色动作更加流畅和逼真的核心。在Unity引擎中&#xff0c;我们可以使用动画混合树&#xff08;Blend Trees&#xff09;来实现这一目标。本篇技术博客将深入讨论动画融合技术的实现原理、在Unity中…

jsp前端输入中文数据传到controller变成问号?的解决办法

还是写老师布置的实验的时候&#xff0c;解决了xml文件找不到的问题之后又遇到新的问题&#xff1a;前端登录处输入用户名和密码&#xff0c;结果明明输入的用户名是对的密码也是对的&#xff08;输入的用户名是中文&#xff09;&#xff0c;它就是显示用户名或密码错误。然后我…

高压配电室智能运维

高压配电室智能运维是指通过运用先进的物联网、大数据、云计算等技术&#xff0c;对高压配电室进行智能化、远程化的运行维护&#xff0c;实现高压配电室的安全、高效、经济运行。以下是高压配电室智能运维的主要功能和优势&#xff1a; 实时监测&#xff1a;通过传感器和监测设…

Vue3引入markdown编辑器--Bytemd

字节跳动开源了一款markdown编辑器&#xff0c;bytemd&#xff0c;项目地址&#xff1a;GitHub - bytedance/bytemd: ByteMD v1 repository 安装 npm i bytemd/vue-next 引入方式如下&#xff0c;再main.js中引入样式 import bytemd/dist/index.css 直接封装一个Markdown编…

JavaEE进阶学习:SpringBoot 的创建和使用

1.什么是Spring Boot Spring 的诞生是为了简化 Java 程序的开发的&#xff0c;而 Spring Boot 的诞生是为了简化 Spring 程序开发的。 Spring Boot 翻译一下就是 Spring 脚手架&#xff0c;它就是为了快速开发 Spring 框架而诞生的 2.Spring Boot 优点 起步依赖 (创建的时候…

深入浅出理解kafka

1.Kafka简介 Kafka 本质上是一个 MQ&#xff08;Message Queue&#xff09;&#xff0c;使用消息队列的优点&#xff1a; 解耦&#xff1a;允许独立的扩展或修改队列两边的处理过程。可恢复性&#xff1a;即使一个处理消息的进程挂掉&#xff0c;加入队列中的消息仍然可以在系…

Android,JNI开发和NDK之间的联系

Android&#xff0c;JNI开发和NDK。 1.jni和ndk jni是在jdk中就有出现的 在我们jdk路径中 D:\java\jdk11\include 这就是jdk中的jni Android开发环境中的ndk也有jni&#xff0c; D:\Android\sdk\ndk\20.0.5594570\toolchains\llvm\prebuilt\windows-x86_64\sysroot\usr\in…

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

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

价差后的几种方向,澳福如何操作才能盈利

在价差出现时&#xff0c;澳福认为会出现以下几种方向。 昂贵资产的贬值和便宜资产的平行升值。昂贵的资产贬值&#xff0c;而便宜的资产保持不变。昂贵资产的贬值和便宜资产的平行贬值&#xff0c;但昂贵资产的贬值速度更快&#xff0c;超过便宜资产。更贵的一对的进一步升值和…

python pyaudio对音频进行端点检测,检测出说话区间

python pyaudio对音频进行端点检测&#xff0c;检测出说话区间 主要采用过零率和语音能量来进行检测&#xff0c;并设置双阈值。 代码如下&#xff1a; # -*- coding: utf-8 -*- import wave import os import matplotlib.pyplot as plt import numpy as np# 判断是否变号 de…

大数据技术学习笔记(四)—— HDFS

目录 1 HDFS 概述1.1 HDFS 背景与定义1.2 HDFS 优缺点1.3 HDFS 组成架构1.4 HDFS 文件块大小 2 HDFS的shell操作2.1 上传2.2 下载2.3 HDFS直接操作 3 HDFS的客户端操作3.1 Windows 环境准备3.2 获取 HDFS 的客户端连接对象3.3 HDFS文件上传3.4 HDFS文件下载3.5 HDFS删除文件和目…

Lab 3: Recursion, Tree Recursion(CS61A 2020)

在网上没有lab3相应的答案&#xff0c;作者也卡蛮久 作者可能就自己的卡住过的问题做一些总结&#xff0c;不能面面俱到&#xff0c;请见谅 &#xff08;就此补充一下答案&#xff09;&#xff08;完整答案在最后&#xff09; Q2: WWPD: Journey to the Center of the Earth…

AcW730.机器人跳跃问题(二分法)-Java版

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader;//由题目可知,无论能量大与小,都满足 e 2 * e - h[i]; //初始能量越大,最终的结果越大,要找到一个满足条件的最小值 //可以根据二分的向左找模板: /*if(check(mid)) r mid;els…

【C++ STL】vector类最全详解(什么是vector?vector类的常用接口有哪些?)

目录 一、前言 二、什么是vector ? &#x1f4a6; vector的基本概念 &#x1f4a6;vector的作用是什么 &#x1f4a6;总结 三、 vector的(一维)定义 四、vector(一维)常用接口的使用 &#x1f4a6;vector的常见构造&#xff08;初始化&#xff09; &#x1f4a6;vector…

11. 哈希冲突

上一节提到&#xff0c;通常情况下哈希函数的输入空间远大于输出空间&#xff0c;因此理论上哈希冲突是不可避免的。比如&#xff0c;输入空间为全体整数&#xff0c;输出空间为数组容量大小&#xff0c;则必然有多个整数映射至同一桶索引。 哈希冲突会导致查询结果错误&#…

探索人工智能领域——每日20个名词详解【day6】

目录 前言 正文 总结 &#x1f308;嗨&#xff01;我是Filotimo__&#x1f308;。很高兴与大家相识&#xff0c;希望我的博客能对你有所帮助。 &#x1f4a1;本文由Filotimo__✍️原创&#xff0c;首发于CSDN&#x1f4da;。 &#x1f4e3;如需转载&#xff0c;请事先与我联系以…

C++ 指针详解

目录 一、指针概述 指针的定义 指针的大小 指针的解引用 野指针 指针未初始化 指针越界访问 指针运算 二级指针 指针与数组 二、字符指针 三、指针数组 四、数组指针 函数指针 函数指针数组 指向函数指针数组的指针 回调函数 指针与数组 一维数组 字符数组…

【C++】C/C++内存管理

前言&#xff1a; 前面我们已经学习了类与对象&#xff0c;认识了六个默认成员函数。这一篇文章我们来学习C/C内存管理&#xff0c;深入了解这套机制有利于我们之后写出更好的C/C程序。 一、C/C内存分布&#xff1a; 1.C/C中程序内存区域划分&#xff1a; 在C中&#xff0c;内…