【定时任务】---- xxl-job、@Scheduled

news2024/11/16 19:57:34

一、@Scheduled注解实现的定时任务

要实现计划任务,首先通过在配置类注解@EnableScheduling来开启对计划任务的支持,然后在要执行计划任务的方法上注解@Scheduled,声明这是一个计划任务。

在Spring Boot 的入口类 XXXApplication 中,必然会有@SpringBootApplication注解,用来标注项目入口,以及完成一些基本的自动自动配置。所以Spring Boot 的项目,可以在启动类中注解@EnableScheduling。

配置类:
在这里插入图片描述计划任务执行类:
在这里插入图片描述其中Scheduled注解中有以下几个参数:
  1.cron是设置定时执行的表达式,如 0 0/5 * * * ?每隔五分钟执行一次 秒 分 时 天 月,cron表达式支持使用占位符
  2.zone表示执行时间的时区
  3.fixedDelay 和fixedDelayString 表示一个固定延迟时间执行,上个任务完成后,延迟多长时间执行
  4.fixedRate 和fixedRateString表示一个固定频率执行,上个任务开始后,多长时间后开始执行
  5.initialDelay 和initialDelayString表示一个初始延迟时间,第一次被调用前延迟的时间

如果多个定时任务定义的是同一个时间,会根据程序加载标有 @Scheduled 方法的先后来执行。若某个定时任务一直无法执行完成,则无法设置下次任务执行时间,之后会导致此任务后面的所有定时任务无法继续执行,也就会出现所有的定时任务罢工的现象。所以应用SpringBoot 的定时任务的方法中,一定不要出现“死循环”、“执行耗费大量时间”、“http持续等待无响应”的现象,否则会导致定时任务直接罢工。针对数据量、查询或者远程调用特别多的场景,推荐把定时任务分段处理。

优点:
不需要依赖外部框架。
简单快速实现任务。@EnableScheduling、@Scheduled 注解

缺点:
无法管理任务。要停止某个任务,必须重新发布。
不支持动态调整。修改任务参数需要重启项目。
不支持集群方式部署。集群模式下会出现任务多次被调度执行的情况,因为集群的节点之间是不会共享任务信息的,每个节点上的任务都会按时执行。

单体,即一个项目部署在一台服务器上;
集群,即将单体复制多份部署在多台服务器,其中每个单体被称为一个节点。

二、xxl-job实现的定时任务

1、xxl-job的使用

1. 简介

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

解压源码,按照maven格式将源码导入IDE, 使用maven进行编译即可,源码结构如下:
xxl-job-admin:调度中心
xxl-job-core:公共依赖
xxl-job-executor-samples:执行器Sample示例(选择合适的版本执行器,可直接使用,也可以参考其并将现有项目改造成执行器)
xxl-job-executor-sample-springboot:Springboot版本,通过Springboot管理执行器,推荐这种方式;
xxl-job-executor-sample-spring:Spring版本,通过Spring容器管理执行器,比较通用;
xxl-job-executor-sample-frameless:无框架版本;
在这里插入图片描述

在xxl-job中,有2个角色:
xxl-job-admin调度中心: 统一管理任务调度平台上的调度任务,负责触发调度执行,并且提供任务管理平台。
xxl-job-executor执行器: 执行器通常是我们的业务系统,如示例中的springboot项目。

设计思想:
将调度行为抽象形成“调度中心”公共平台,而平台自身并不承担业务逻辑,“调度中心”负责发起调度请求。

将任务抽象成分散的JobHandler,交由“执行器”统一管理,“执行器”负责接收调度请求并执行对应的JobHandler中业务逻辑。因此,“调度”和“任务”两部分可以相互解耦,提高系统整体稳定性和扩展性。

xxl-job就是一个中心化管理系统,系统主要通过MySQL管理各种定时任务信息,当到了定时任务的触发时间,就把任务信息从数据库中拉进内存,对任务执行器发起调度请求。
在这里插入图片描述

2. 使用

①下载源码 : https://github.com/xuxueli/xxl-job/

②初始化“调度数据库”:
到官网下载项目源码并解压,获取 “调度数据库初始化SQL脚本” 并执行即可,正常情况下应该生成16张表。SQL脚本位置:/xxl-job/doc/db/tables_xxl_job.sql

表名作用
xxl_job_group执行器信息表:维护任务执行器信息
xxl_job_info调度扩展信息表:用于保存xxl-job调度任务的扩展信息,如任务分组、任务名、机器地址、执行器、执行入参和报警邮件等等
xxl_job_lock任务调度锁表
xxl_job_log调度日志表:用于保存xxl-job调度任务的历史信息,如调度结果、执行结果、调度入参、调度机器和执行器等等
xxl_job_log_report调度日志报表:用户存储xxl-job任务调度日志的报表,调度中心报表功能页面会用到
xxl_job_logglue任务GLUE日志:用于保存GLUE更新历史,用于支持GLUE的版本回溯功能
xxl_job_registry执行器注册表:维护在线的执行器和调度中心机器地址信息
xxl_job_user系统用户表

注意⚠️:调度中心支持集群部署,集群情况下各节点务必连接同一个mysql实例;
如果mysql做主从,调度中心集群节点务必强制走主库

步骤一:调度中心(xxl-job-admin)配置、部署等

调度中心项目: xxl-job-admin
作用: 统一管理任务调度平台上调度任务,负责触发调度执行,并且提供任务管理平台。
调度中心配置文件地址: /xxl-job/xxl-job-admin/src/main/resources/xxl-job-admin.properties

### 调度中心JDBC链接
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl-job?Unicode=true&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=root_pwd
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

### 报警邮箱
spring.mail.host=smtp.qq.com
spring.mail.port=25
spring.mail.username=xxx@qq.com
spring.mail.password=xxx
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true

### 登录账号
xxl.job.login.username=admin
xxl.job.login.password=123456

### 调度中心通讯TOKEN,用于调度中心和执行器之间的通讯进行数据加密,非空时启用
xxl.job.accessToken=

### 调度中心国际化设置,默认为中文版本,值设置为“en”时切换为英文版本
xxl.job.i18n=

启动:部署项目
如果已经正确进行上述配置,可将项目编译打包部署。 调度中心访问地址:http://localhost:8080/xxl-job-admin (该地址执行器将会使用到,作为回调地址),登录后运行界面如下图所示 默认登录账号 “admin/123456”
在这里插入图片描述至此“调度中心”项目已经部署成功。

调度中心集群:
调度中心支持集群部署,提升调度系统容灾和可用性。
调度中心集群部署时,几点要求和建议:

  • DB配置保持一致;
  • 登陆账号配置保持一致;
  • 集群机器时钟保持一致(单机集群忽视);
  • 建议:推荐通过nginx为调度中心集群做负载均衡,分配域名。调度中心访问、执行器回调配置、调用API服务等操作均通过该域名进行。

步骤二. xxl-job-executor执行器 在项目中的配置使用

xxl-job-excutor是任务的执行单元,需要在业务系统中实现。

步骤一:在你的项目里引入xxl-job-core的依赖
<dependency>
  <groupId>com.xuxueli</groupId>
  <artifactId>xxl-job-core</artifactId>
  <version>2.0.1</version>
</dependency>
步骤二:在项目的配置文件中添加

web和执行器端口号不同,调度中心地址addresses和执行器应用名appname保持一致

### 调度中心部署跟地址 [选填]:如调度中心集群部署存在多个地址则用逗号分隔。执行器将会使用该地址进行"执行器心跳注册""任务结果回调";为空则关闭自动注册;
xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin

### 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册
xxl.job.executor.appname=xxl-job-executor-athena

### 执行器IP [选填]:默认为空表示自动获取IP,多网卡时可手动设置指定IP,该IP不会绑定Host仅作为通讯实用;地址信息用于 "执行器注册""调度中心请求并触发任务";
xxl.job.executor.ip=

### 执行器端口号 [选填]:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口;
xxl.job.executor.port=9999

### 执行器通讯TOKEN [选填]:非空时启用;
xxl.job.accessToken=

### 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径;
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler

### 执行器日志保存天数 [选填] :值大于3时生效,启用执行器Log文件定期清理功能,否则不生效;
xxl.job.executor.logretentiondays=-1
步骤三:添加XxlJobConfig配置类:

在XxljobConfig中初始化一个XxlJobSpringExecutor,该类用于处理xxl-job-admin和xxl-job-excutor之间的通讯以及任务的处理。

package com.xxl.job.executor.core.config;

import com.xxl.job.core.executor.XxlJobExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * xxl-job config
 *
 * @author xuxueli 2017-04-28
 */
@Configuration
@ComponentScan(basePackages = "com.xxl.job.executor.service.jobhandler")
public class XxlJobConfig {
    private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);

    @Value("${xxl.job.admin.addresses}")
    private String adminAddresses;

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

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

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

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

    @Value("${xxl.job.executor.logpath}")
    private String logPath;

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


    @Bean(initMethod = "start", destroyMethod = "destroy")
    public XxlJobExecutor xxlJobExecutor() {
        logger.info(">>>>>>>>>>> xxl-job config init.");
        XxlJobExecutor xxlJobExecutor = new XxlJobExecutor();
        xxlJobExecutor.setAdminAddresses(adminAddresses);
        xxlJobExecutor.setAppName(appName);
        xxlJobExecutor.setIp(ip);
        xxlJobExecutor.setPort(port);
        xxlJobExecutor.setAccessToken(accessToken);
        xxlJobExecutor.setLogPath(logPath);
        xxlJobExecutor.setLogRetentionDays(logRetentionDays);

        return xxlJobExecutor;
    }
}
步骤四:在项目中创建任务

1、继承”IJobHandler”:“com.xxl.job.core.handler.IJobHandler”;
2、注册到Spring容器:添加“@Component”注解,被Spring容器扫描为Bean实例;
3、注册到执行器工厂:添加“@JobHandler(value=”自定义jobhandler名称”)”注解,注解value值对应的是调度中心新建任务的JobHandler属性的值。

@JobHandler(value="jobtest")
@Component
public class job_test extends IJobHandler {
    @Override
    public ReturnT<String> execute(String s) throws Exception {
         try {
            System.out.println("测试~~~");
            /*测试数据*/
            return SUCCESS;
        } catch (Exception e){
            e.printStackTrace();
            return FAIL;
        }
    }
}
步骤五:执行器项目集群(可选)

执行器支持集群部署,提升调度系统可用性,同时提升任务处理能力。
执行器集群部署时,几点要求和建议:

  • 执行器回调地址(xxl.job.admin.addresses)需要保持一致;执行器根据该配置进行执行器自动注册等操作
  • 同一个执行器集群内AppName(xxl.job.executor.appname)需要保持一致;调度中心根据该配置动态发现不同集群的在线执行器列表

步骤三. 使用调度中心

1、执行器管理

在这里插入图片描述在这里插入图片描述注意:当是自动注册的时候,会根据appname寻找执行器机器地址,此时Appname 必须和 application.properties 执行器配置文件中appname 保持一致.
如果手动注册,appname 可以不一致,但是机器地址必须和xxl.job.executor.ip 保持一致.

xxl.job.executor.appname=xxl-job-executor-sample
xxl.job.executor.ip=192.168.21.168
xxl.job.executor.port=9999

执行器属性说明
AppName: 是每个执行器集群的唯一标示AppName, 执行器会周期性以AppName为对象进行自动注册。可通过该配置自动发现注册成功的执行器, 供任务调度时使用;

名称: 执行器的名称, 因为AppName限制字母数字等组成,可读性不强, 名称为了提高执行器的可读性;

排序: 执行器的排序, 系统中需要执行器的地方,如任务新增, 将会按照该排序读取可用的执行器列表;

注册方式:调度中心获取执行器地址的方式;

自动注册:执行器自动进行执行器注册,调度中心通过底层注册表可以动态发现执行器机器地址;

手动录入:人工手动录入执行器的地址信息,多地址逗号分隔,供调度中心使用;

机器地址:”注册方式”为”手动录入”时有效,支持人工维护执行器的地址信息;

2、任务管理

在这里插入图片描述点击新增任务后创建任务
jobhandler里的内容需要与任务代码中@jobhandler的value 保持一致.

运行模式:

  • BEAN模式:支持基于类的开发方式,每个任务对应一个Java类。
  • GLUE模式:任务以源码方式维护在调度中心,支持通过Web IDE在线更新,实时编译和生效,因此不需要指定JobHandler。
    在这里插入图片描述路由策略: 集群模式下某个任务选择由哪个执行器完成的策略。
    在这里插入图片描述
3、日志管理,执行任务后,在调度中心可以查看调度日志。在这里插入图片描述

调度时间:”调度中心”触发本次调度并向”执行器”发送任务执行信号的时间;
调度结果:”调度中心”触发本次调度的结果,200表示成功,500或其他表示失败;
调度备注:”调度中心”触发本次调度的日志信息;
执行器地址:本次任务执行的机器地址
运行模式:触发调度时任务的运行模式,运行模式可参考章节 “三、任务详解”;
任务参数:本地任务执行的入参
执行时间:”执行器”中本次任务执行结束后回调的时间;

查看两个临近的调度结果,可以发现任务是由两个执行器轮询执行的。
在这里插入图片描述在这里插入图片描述

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

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

相关文章

东南大学洪伟教授评述:毫米波与太赫兹技术

今日推荐文章作者为东南大学毫米波国家重点实验室主任、IEEE Fellow 著名毫米波专家洪伟教授&#xff0c;本文选自《毫米波与太赫兹技术》&#xff0c;发表于《中国科学: 信息科学》2016 年第46卷第8 期——《信息科学与技术若干前沿问题评述专刊》。 本文概要介绍了毫米波与太…

CSS知识点精学6-精灵图、背景图片大小、文字阴影、盒子阴影、过渡

目录 一.精灵图 1.精灵图的介绍 2.精灵图的使用步骤 二.背景图片大小 三.文字阴影 四.盒子阴影 五.过渡 一.精灵图 1.精灵图的介绍 场景&#xff1a;项目中将多张小图片&#xff0c;合成一张大图片&#xff0c;这张图片称之为精灵图 优点&#xff1a;减少服务器发送次…

clickhouse入门学习以及数据迁移

本文主要介绍如何入门clickhouse&#xff0c;以及将mariadb数据迁移过来&#xff0c;最后介绍当前几种的训练的示例数据库集。1、中文教程&#xff1a;中文教程&#xff1a;中文教程有了教程&#xff0c;需要有数据可以训练&#xff0c;教程提供示例数据集&#xff0c;但是数据…

Java基础之《netty(22)—Protobuf》

一、Protobuf基本介绍 1、Protobuf是Google发布的开源项目&#xff0c;全称Google Protobuf Buffers&#xff0c;是一种轻便高效的结构化数据存储格式&#xff0c;可以用于结构化数据串行化&#xff0c;或者说序列化。它很适合做数据存储或RPC数据交换格式。 2、参考文档 htt…

粒子系统-主模块参数

目录 Duration Looping Prewarm Start Lifttime Start Speed Start Size 3D Start Rotation Start Rotation Start color Simulation Space Max Particles Duration 粒子系统的工作时长&#xff0c;如果不勾选Looping的话&#xff0c;在5秒后就再也没有粒子发射 L…

HTTPS头部的Referer字段

目录 Referrer-policy 如何设置referer 盗链 防盗链的工作原理 绕过图片防盗链 利用https网站盗链http资源网站&#xff0c;refer不会发送 利用iframe伪造请求referer 利用XMLHttpRequest Referer请求头包含了当前请求页面的来源页面的地址&#xff0c;即表示当前页面是…

【Proteus仿真】【STM32单片机】智能窗帘控制系统设计

文章目录一、功能简介二、软件设计三、实验现象联系作者一、功能简介 本项目使用Proteus8仿真STM32单片机控制器&#xff0c;使用LCD1602显示模块、按键模块、HC05蓝牙、DHT11温湿度、PCF8591 ADC模块、光线传感器、28BYJ48步进电机等。 主要功能&#xff1a; 系统运行后&…

链表算法-回文结构、两个链表公共节点

最近一直在刷算法&#xff0c;以前没有重视这块&#xff0c;偶然巧合下&#xff0c;想到了某几次的面试&#xff0c;虽然没有以这个为主&#xff0c;但是也都有问过算法的题&#xff0c;因为没有这方面的积累&#xff0c;所以心底里一直抗拒&#xff0c;最近也有时间&#xff0…

git第n次学习笔记

git工作流程git四个工作区域Workspace&#xff1a;工作区&#xff0c;就是你平时存放项目代码的地方Index/Stage&#xff1a;暂存区&#xff0c;用于临时存放你的改动&#xff0c;事实上它只是一个文件&#xff0c;保存即将提交到文件列表信息Repository&#xff1a;仓库区&…

CDGA|想做好数据安全,数据治理是核心

在数字化转型渐进成熟下&#xff0c;企业加强数据治理&#xff0c;保障数据安全&#xff0c;为数字经济持续发展筑牢安全屏障&#xff0c;是时代发展的客观需要。 首先&#xff0c;整个安全能力是在应用内部的&#xff0c;我们对数据流的精确感知和管控&#xff0c;能做到和应用…

【七】Netty JBoss Marshallin 编解码

Netty JBoss Marshallin 编解码介绍Marshallin 开发环境maven 依赖业务场景模拟流程图代码展示订购采购消息 POJO 类订购应答消息 POJO 类SubscribeReqServer 服务端启动类MarshallingCodeCFactory服务端业务处理类 SubscribeServerHandler客户端启动类 SubscribeClient客户端 …

leetcode.2471 逐层排序二叉树所需的最少操作数目 - bfs + 置换环算法 + 并查集

2471. 逐层排序二叉树所需的最少操作数目 目录 1、循环标记置换环 2、并查集置换环 思路&#xff1a; 总操作数目 每一层最小操作数之和 每一层元素个数 - 置换环数 先用bfs对树进行层序遍历&#xff0c;一层一层地计算 置换环&#xff1a;对每个节点&#xff0c;将其指向…

全国首例:新一代仿生型人工心脏在福建成功植入

此时此刻&#xff0c;福建福清吴先生的体内正搏动着一颗新款的“人工心脏”。心脏是生命的中枢&#xff0c;一旦衰竭生命也将终止&#xff0c;人工心脏为这些心衰患者带来了新的希望。福建医科大学附属协和医院心外科团队&#xff0c;将科幻电影里装着人工心脏的“钢铁侠”变成…

六派巨量转移技术概述

1. 巨量转移技术概述 与OLED显示技术不同&#xff0c;无机LED无法在玻璃或其他大尺寸衬底进行大面积的制作&#xff0c;因此需要在半导体衬底上进行制作&#xff0c;然后再转移到驱动背板上。当前LED所采用的衬底一般为蓝宝石&#xff0c;但蓝宝石与外延层之间的晶格和热膨胀系…

国产技术迎来突破,光量子芯片横空出世,中文编程也有好消息

国外光刻机不再牛&#xff0c;随着这项技术问世&#xff0c;我们摆脱芯片卡脖子困境成为可能&#xff01; 欧美技术如此领先&#xff0c;我们凭什么实现弯道超车&#xff1f;就凭国内领先全球的量子技术&#xff0c;还有惊艳问世的光量子芯片&#xff0c;让欧美震惊不已&#x…

Fossid简介及API接口调用开发

FOSSID简介 FOSSID 是由瑞典FOSSID 公司开发的一款开源代码检测和管理工具&#xff0c;能够全面、准确、高效的发现用户代码库中的开源代码及其风险。 FOSSID 是一个软件解决方案&#xff0c;能够单独部署使用&#xff0c;也可以与现有的开发流程进行无缝集成&#xff0c;能够…

Apache Shiro教程(4)

shiro授权 授权 授权&#xff0c;即访问控制&#xff0c;控制谁能访问哪些资源&#xff0c;主体进行身份认证后需要分配权限方可访问系统的资源&#xff0c;对于某些资源没有权限是无法访问的。 关键对象 授权可简单理解为 who 对 what 进行how操作 授权流程 授权方式 基于角…

如何优化Blender内存不足问题

众所周知&#xff0c; Blender是一款免费软件&#xff0c;在动画、3D 电影等所有领域都易于使用。您是否曾经在 Blender 场景中工作&#xff0c;突然无缘无故崩溃&#xff1f;或者简单地说&#xff0c;您在渲染过程中突然移动缓慢甚至导致卡顿。当你有最后期限时&#xff0c;这…

13_4、Java的IO流之缓冲流的使用

一、引入为了提高数据读写的速度&#xff0c;Java API提供了带缓冲功能的流类&#xff0c;在使用这些流类 时&#xff0c;会创建一个内部缓冲区数组&#xff0c;缺省使用8192个字节(8Kb)的缓冲区。 二、缓冲流涉及到的类字节输入流&#xff1a;BufferedInputStream 字节输出流B…

pytorch入门理解

一、入门操作 1、创一个tensor矩阵 x torch.rand(5, 3) x out&#xff1a; tensor([[0.5051, 0.7017, 0.0170],[0.1441, 0.2476, 0.5710],[0.0452, 0.8690, 0.2387],[0.5709, 0.0098, 0.6993],[0.3203, 0.5124, 0.1010]])创建好后可以直接打印&#xff0c;要比tensorflow好用…