首页 > 其他分享 >XXL-JOB快速入门(什么是XXL-JOB、部署XXL-JOB、在SpringBoot项目中接入XXL-JOB、XXL-JOB中的核心概念、集群环境下任务的路由策略)

XXL-JOB快速入门(什么是XXL-JOB、部署XXL-JOB、在SpringBoot项目中接入XXL-JOB、XXL-JOB中的核心概念、集群环境下任务的路由策略)

时间:2024-11-20 11:45:08浏览次数:3  
标签:执行器 SpringBoot JOB job 任务 XXL xxl

文章目录

1. 分布式任务调度

分布式任务调度是一种在分布式系统中协调和执行任务的方法。在分布式计算环境中,任务调度器负责将任务分配到不同的计算节点上,以优化资源利用、提高任务处理效率、保证任务执行的可靠性。


分布式任务调度的几个关键点:

  1. 任务分配:根据任务的性质、资源的需求以及各节点的状态,将任务合理地分配到不同的节点上执行。
  2. 负载均衡:在多个节点之间平衡任务负载,避免某些节点过载而其他节点空闲的情况,从而提高系统整体的处理能力。
  3. 容错机制:当某个节点发生故障时,任务调度系统能够将任务重新分配到其他健康的节点上,确保任务的连续性和系统的稳定性。
  4. 资源管理:管理各个节点的资源使用情况,包括CPU、内存、存储和网络等,确保任务能够获得必要的资源。
  5. 任务监控:监控任务的执行状态,收集性能数据,为调度决策提供依据。
  6. 任务依赖管理:处理任务之间的依赖关系,确保前置任务完成后才开始后续任务。

分布式任务调度的常见应用场景:

  • 大数据处理:在处理大规模数据集时,通过分布式任务调度来实现数据的并行处理。
  • 实时计算:在需要实时响应的场景中,如实时数据分析、在线推荐系统等,分布式任务调度可以保证计算的时效性。
  • 批量作业:定时执行批量作业,如数据备份、报表生成等。
  • 微服务架构:在微服务架构中,分布式任务调度有助于服务之间的协调和通信。

分布式任务调度的工具和框架有很多,如Apache Hadoop的YARN、Apache Mesos、Kubernetes、以及国产的调度工具如XXL-JOB、Elastic-Job等。这些工具和框架提供了任务调度、资源管理、容错处理等功能,使得在分布式环境中管理和执行任务变得更加高效和可靠

在这里插入图片描述

2. @Scheduled注解的局限

利用 Spring 框架提供的 @Scheduled 注解可以比较方便地设置定时任务,但是使用 @Scheduled 注解存在以下问题:

  1. 集群环境下任务的重复执行问题(虽然可以通过分布式锁解决这个问题,但是比较麻烦)
  2. CRON 表达式定义在代码之中,不方便修改
  3. 如果定时任务执行失败,无法重试,也没有统计信息
  4. 如果任务量过大,任务不能有效地分片执行

3. 什么是XXL-JOB

XXL-JOB 是一个分布式任务调度平台,由中国人许雪里(一个来自美团的程序员)开发

XXL-JOB 的核心设计目标是开发迅速、学习简单、轻量级、易扩展,XXL-JOB 现已开放源代码并接入多家公司的线上产品线


源码地址:许雪里/xxl-job

文档地址:XXL开源社区

在这里插入图片描述

在这里插入图片描述

4. 通过源码部署调度中心

调度中心环境要求

  • Maven3+
  • Jdk1.8+
  • Mysql5.7+

4.1 下载源码

我们先下载把 XXL-JOB 的源码(下载地址:许雪里/xxl-job

在这里插入图片描述

下载 zip 压缩包

在这里插入图片描述

4.2 源码说明

由于 XXL-JOB 是用 Java 开发的,我们可以用 IDEA 打开 XXL-JOB 的源码

在这里插入图片描述

4.3 运行数据库脚本

找到 doc 目录下的 tables_xxl_job.sql 文件,执行 SQL 文件(XXL-JOB 的运行依赖于一个名为 xxl-job 数据库,数据库中有 8 张表)

在这里插入图片描述

4.4 补充:xxl_job数据库中八张表的作用

八张表的作用:

表名作用
xxl_job_info存储任务的基本信息,如任务名称、执行器信息、调度规则等。
xxl_job_log存储任务的执行日志,包括任务执行状态、执行耗时、执行结果等。
xxl_job_logglue存储任务的 Glue 配置信息,如 Glue 类型、Glue 源码等。
xxl_job_trigger_log存储任务的触发日志,包括任务触发时间、触发结果等。
xxl_job_user存储用户信息,如用户名、密码、角色等。
xxl_job_group存储执行器分组信息,如执行器分组名称、执行器信息等。
xxl_job_registry存储执行器的注册信息,如执行器 IP、端口、心跳间隔等。
xxl_job_lock存储任务执行时的锁信息,以避免任务并发执行。

4.5 调度中心配置

4.5.1 数据库相关配置

配置文件位置:xxl-job-master/xxl-job-admin/src/main/resources/application.properties

在这里插入图片描述

修改与数据库相关的信息

spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

4.5.2 日志相关配置

配置文件位置:xxl-job-master/xxl-job-admin/src/main/resources/logback.xml

修改日志文件的存放路径

在这里插入图片描述

4.6 启动调度中心

启动 XxlJobAdminApplication

在这里插入图片描述

4.7 访问调度中心

在浏览器输入以下地址

http://localhost:8080/xxl-job-admin
  • 默认的登录账号:admin
  • 默认的登录密码:123456

在这里插入图片描述

成功登录后的界面

在这里插入图片描述

4.8 修改密码(可选)

在调度中心修改密码

在这里插入图片描述

4.9 补充:账号和密码的存放位置

XXL-JOB 的账号和密码存放在 xxl_job 数据库的 xxl_job_user 表中

表中默认有一个名为 admin 的用户,密码是 123456(数据库中存储的密码是经过加密后的字符串)

在这里插入图片描述

  • role:角色:0-普通用户、1-管理员
  • permission:权限:执行器ID列表,多个逗号分割

5. 通过docker部署调度中心

5.1 拉取镜像

sudo docker pull xuxueli/xxl-job-admin:2.4.1

在这里插入图片描述

下载好 xxl-job 的镜像后,可以将镜像保存为 tar 文件,下载到 Windows 本地,方便下一次在另一个 Linux 系统上运行

sudo docker save xuxueli/xxl-job-admin:2.4.1 -o /tmp/xxl-job-admin-2.4.1.tar
sudo chmod +rx /tmp/xxl-job-admin-2.4.1.tar

5.2 启动容器

修改与数据库有关的信息

sudo docker run \
  -e 'PARAMS=--spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl_job?Unicode=true&characterEncoding=UTF-8 \
  --spring.datasource.username=wuyanzu \
  --spring.datasource.password=!UpuSZAxG#1&2^cG \
  --xxl.job.accessToken=default_token \
  --server.port=8080' \
  -p 8080:8080 \
  -v /tmp:/data/applogs \
  --name xxl-job-admin \
  -d xuxueli/xxl-job-admin:2.4.1

指令的解释

  • -e 'PARAMS=... --server.port=8080': 这是设置环境变量 PARAMS,它包含了 XXL-JOB admin 服务启动时需要的一系列参数。参数之间用空格分隔,具体包括:
    • --spring.datasource.url: 指定 Spring Boot 应用的数据源 URL。
    • --spring.datasource.username: 数据库的用户名。
    • --spring.datasource.password: 数据库的密码。
    • --xxl.job.accessToken: XXL-JOB 的访问令牌,用于 API 访问控制。
    • --server.port: 指定服务运行的端口号。
  • -p 8080:8080: 这是指定端口映射,将容器的 8080 端口映射到宿主机的 8080 端口。
  • -v /tmp:/data/applogs: 这是指定卷映射,将宿主机的 /tmp 目录映射到容器的 /data/applogs 目录,用于存储日志文件。
  • --name xxl-job-admin: 这是为容器设置一个名称,这里命名为 xxl-job-admin
  • -d: 这是指定容器在后台运行。
  • xuxueli/xxl-job-admin:2.4.1: 这是指定要运行的 Docker 镜像,这里是 xuxueli/xxl-job-admin 镜像的 2.4.1 版本。

5.3 开放防火墙的端口

为了能够从外界访问 XXL-JOB,需要为 XXL-JOB 开放防火墙的 8080 端口

  1. 如果你使用的是云服务器,在安全组中放行 8080 端口
  2. 如果你安装了宝塔,除了在安全组中放行 8080 端口,还要在宝塔中放行 8080 端口

完成以上两个操作后,输入以下指令开放 9000 端口 和 9090 端口

ubuntu

sudo ufw allow 8080 
sudo ufw reload

CentOS

sudo firewall-cmd --zone=public --add-port=8080 /tcp --permanent
sudo firewall-cmd --reload

5.4 访问调度中心

在浏览器输入以下地址(将 localhost 更改为你的 IP 地址)

http://localhost:8080/xxl-job-admin
  • 默认的登录账号:admin
  • 默认的登录密码:123456

5.5 注意事项

XXL-JOB 的运行依赖于数据库,通过 docker 部署 XXL-JOB 时,确保调度中心能连接到数据库

使用一个公网可以访问的数据库是最简单的方法

6. 在SpringBoot项目中接入XXL-JOB

6.1 新建执行器

在调度中心中新建执行器(默认情况下会有一个名为 xxl-job-executor-sample 的执行器)

在这里插入图片描述

6.2 新建任务

在调度中心中新建任务(默认情况下会有一个名为 测试任务1 的任务)

在这里插入图片描述

任务的 JobHandler 属性下面会用到

0/1 * * * * ? * 表示每秒执行一次

0/1 * * * * ? *

在这里插入图片描述

6.3 引入依赖

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

6.4 编写与XXL-JOB相关的配置

XXL-JOB 会启动一个内嵌的服务器,该内嵌服务器默认会占用 9999 端口,可以指定

application.yml

server:
  port: 8881

xxl:
  job:
    access-token: default_token
    admin:
      addresses: http://127.0.0.1:8080/xxl-job-admin
    executor:
      app-name: xxl-job-executor-sample
      ip : localhost
      port: 11015

6.5 编写XXL-JOB配置类

import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
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.Configuration;

@Configuration
public class XxlJobConfiguration {

    private final Logger logger = LoggerFactory.getLogger(XxlJobConfiguration.class);

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

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

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

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

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

    @Bean
    public XxlJobSpringExecutor xxlJobSpringExecutor() {
        logger.info("============================== xxlJobSpringExecutor ==============================");
        XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
        xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
        xxlJobSpringExecutor.setAppname(appName);
        xxlJobSpringExecutor.setAccessToken(accessToken);
        xxlJobSpringExecutor.setIp(ip);
        xxlJobSpringExecutor.setPort(port);
        xxlJobSpringExecutor.setLogPath("F:\\HeiMaTouTiao\\xxl-job\\executor");
        logger.info("============================== xxlJobSpringExecutor ==============================");

        return xxlJobSpringExecutor;
    }

}

6.6 编写任务代码

使用 @XxlJob 注解指定要执行哪个任务

import com.xxl.job.core.handler.annotation.XxlJob;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class HelloXxlJob {

    @Value("${server.port}")
    private String port;

    @XxlJob("demoJobHandler")
    public void echo() {
        System.out.println("Hello, XXL-JOB" + port);
    }

}

6.7 启动任务

先启动 SpringBoot 应用程序(SpringBoot 应用程序启动后会自动注册到调度中心)

在这里插入图片描述

接着在调度中心启动任务

在这里插入图片描述

任务启动后就能在控制台看到输出了

在这里插入图片描述

7. XXL-JOB中的核心概念

7.1 执行器(Executor)

在这里插入图片描述

在 XXL-JOB 中,执行器(Executor)是指那些实际执行任务的远程服务。每个执行器都会向 XXL-JOB 的调度中心(Admin)注册自己,并定期发送心跳以保持其注册状态。


XXL-JOB 中执行器的几个关键点:

  1. 注册和心跳:执行器启动后,会向调度中心注册,并在 xxl_job_registry 表中记录其地址(通常是 IP 地址和端口号)。执行器还会定期发送心跳,以证明自己仍然在线并能够接收任务。
  2. 任务执行:当调度中心接收到任务执行请求时,它会根据任务的配置选择一个合适的执行器来执行任务。
  3. 地址记录:在 xxl_job_registry 表中,执行器的地址记录为 registry_value。如果这个值是 localhost,那么它通常意味着执行器和调度中心部署在同一台服务器上。
  4. 本地通信:如果执行器的 registry_valuelocalhost,调度中心通过本地回环接口与执行器通信,不经过网络接口,因此没有网络延迟。
  5. 端口监听:执行器需要监听一个端口(例如 9999),以便调度中心可以发送任务执行请求到这个端口。
  6. 配置注意事项
    • 确保执行器监听的端口没有被其他服务占用。
    • 如果服务器上有防火墙,需要允许本地回环接口上的通信。
    • 考虑到可维护性和可扩展性,建议在非测试和开发环境中使用具体的 IP 地址或域名,而不是 localhost
  7. 迁移和扩展:如果将来需要将执行器迁移到不同的服务器,或者需要扩展系统以处理更多任务,那么需要更新 xxl_job_registry 表中的 registry_value,以反映执行器的新地址。

总的来说,XXL-JOB 中的执行器是任务执行的关键组件,它需要正确地注册和配置,以确保调度中心可以有效地分配和执行任务。

7.2 任务(JOB)

在这里插入图片描述

7.2.1 执行器

每个任务必须绑定一个执行器,方便对任务进行分组

7.2.2 任务描述

任务的描述信息,便于任务管理

7.2.3 负责人

任务的负责人

7.2.4 报警邮件

任务调度失败时邮件通知的邮箱地址,支持配置多邮箱地址,配置多个邮箱地址时用逗号分隔

7.2.5 调度类型

  • :该类型不会主动触发调度
  • CRON:该类型将会通过 CRON 表达式触发任务调度
  • 固定速度:该类型将会以固定速度,触发任务调度(按照固定的间隔时间,周期性触发)

7.2.6 运行模式

  1. Bean 类型任务
    • 概述:Bean 类型任务通常指的是通过 Spring 容器管理的 Java Bean 类。
    • 执行方式:调度中心会将任务交给 Spring 容器管理的 Java Bean 类进行执行。这种方式适合需要依赖 Spring 环境的任务。
    • 依赖:任务需要依赖 Spring 容器,因此需要将任务对应的 Java Bean 类添加到 Spring 容器中。
    • 配置:在 XXL-JOB 的配置中,需要指定任务的 Bean 类名。
  2. Glue 类型任务
    • 概述:Glue 类型任务通常指的是外部的脚本文件,如 Shell、Python、Java 等。
    • 执行方式:调度中心会将任务交给指定的脚本文件进行执行。这种方式适合需要执行外部脚本的任务。
    • 依赖:任务不需要依赖 Spring 容器,可以直接执行外部脚本。
    • 配置:在 XXL-JOB 的配置中,需要指定任务的 Glue 类型(如 Shell、Python、Java 等)和对应的脚本文件路径。

7.2.7 JobHandler

运行模式为 BEAN 模式时生效,对应 Bean 中 @XxlJob 注解中声明的 value 值

在这里插入图片描述

7.2.8 任务参数

任务执行所需要的参数

7.2.9 阻塞处理策略

调度过于密集,执行器来不及处理时的处理策略:

  1. 单机串行:调度请求进入单机执行器后,调度请求进入 FIF0(First Input First 0utput)队列,以串行方式运行
  2. 丢弃后续调度:调度请求进入单机执行器后,发现执行器存在运行的调度任务,本次请求将会被丢弃并标记为失败
  3. 覆盖之前调度:调度请求进入单机执行器后,发现执行器存在运行的调度任务,将会终止运行中的调度任务并清空队列,然后运行本地调度任务

7.2.10 路由策略

在这里插入图片描述

在 XXL-JOB 中,执行器集群部署时,有以下路由策略:

  1. 第一个(FIRST):任务总是固定选择第一个可用的执行器。
  2. 最后一个(LAST):任务总是固定选择最后一个可用的执行器。
  3. 轮询(ROUND):按照顺序轮流选择可用的执行器。
  4. 随机(RANDOM):随机选择在线的机器。
  5. 一致性HASH(CONSISTENT HASH):使用一致性哈希算法,每个任务固定选择某一台机器,且所有任务均匀散列在不同机器上。
  6. 最不经常使用(LEAST FREQUENTLY_USED):使用频率最低的机器优先被选举。
  7. 最近最久未使用(LEAST RECENTLY_USED):最久未使用的机器优先被选举。
  8. 故障转移(FAILOVER):当第一个执行器失败时,依次尝试下一个执行器,直到找到可用的执行器。
  9. 忙碌转移(BUSYOVER):当第一个执行器忙碌时,依次尝试下一个执行器,直到找到空闲的执行器。
  10. 分片广播(SHARDING BROADCAST):广播触发对应集群中所有机器执行一次任务,同时系统自动传递分片参数。

8. 集群环境下任务的轮询路由策略

我们演示一下集群环境下任务的轮询路由策略

8.1 修改任务的执行策略为轮询

在这里插入图片描述

在这里插入图片描述

8.2 启动多个微服务

右键微服务,点击复制配置

在这里插入图片描述

点击修改选项

在这里插入图片描述

点击添加虚拟机选项

在这里插入图片描述

在虚拟机选项中填入以下内容

-Dserver.port=8882 -Dexecutor.port=11016

在这里插入图片描述

接着修改 application.yml 文件,修改内容如下

port: ${executor.port:11015}

在这里插入图片描述

右键复制出来的微服务,启动程序

在这里插入图片描述

最后启动任务,就可以分别在两个微服务的控制台中看到运行结果了

在这里插入图片描述

在这里插入图片描述

9. 集群环境下任务的分片广播路由策略

9.1 什么情况下采用分片广播

集群环境下,如果任务的路由策略为分片广播,一次任务调度将会广播集群中的所有执行器

举个例子,支付宝的花呗每个月 10 号都会通知用户还款,由于支付宝花呗的用户很多,任务量会特别大,如果使用轮询的方式,任务的执行效率就会变得很低

也就是说,在同一个时间点,要执行大量任务的情况下,会用到分片广播


假如现在有 8 个任务,集群中有三台机器,如果我们要同时地执行任务,就需要为每一个实例分配任务

在这里插入图片描述

那 XXL-JOB 是如何做的呢

假设现在集群中还是有三个实例,XXL-JOB 会通过任务 id 取模(对集群中的实例数取模)的方式让具体的分片执行任务

在这里插入图片描述

9.2 分片广播案例

需求:让两个节点同时执行 10000 个任务,每个节点分别执行 5000 个任务

9.2.1 创建执行器

我们新建一个分片执行器

xxl-job-sharding-executor

在这里插入图片描述

9.2.2 创建任务

我们新建一个任务,用于演示分片广播(记得勾选更改执行器)

0/5 * * * * ? *
shardingJobHandler

在这里插入图片描述

9.2.3 修改配置

修改 application.yml 文件中执行器的名字

xxl-job-sharding-executor

在这里插入图片描述

9.2.4 修改任务代码

在 HelloXxlJob 类中添加以下代码

  • index:当前分片的序号(从0开始),执行器集群列表中当前执行器的序号
  • total:总分片数,执行器集群的总机器数量

在这里插入图片描述

@XxlJob("shardingJobHandler")
public void shardingJobHandler() {
    // 分片参数
    int shardIndex = XxlJobHelper.getShardIndex();
    int shardTotal = XxlJobHelper.getShardTotal();

    // 业务逻辑
    List<Integer> list = getList();
    for (Integer integer : list) {
        if (integer % shardTotal == shardIndex) {
            System.out.println("当前第" + shardIndex + "分片执行了,任务项为:" + integer);
        }
    }
}

public List<Integer> getList() {
    List<Integer> list = new ArrayList<>();

    for (int i = 0; i < 10000; i++) {
        list.add(i);
    }

    return list;
}

9.2.5 重启微服务

分片广播方式:实例 A 和 B 每秒同时接收 10000 个任务,但根据各自分片 id,实例 A 只会处理其中的 5000 个,跳过另外 5000 个,实例 B 同理

重启两个微服务,就可以在控制台中看到分片广播的效果了

在这里插入图片描述

在这里插入图片描述

10. 执行器无法注册到配置中心

参考我的另一篇博文:XXL-JOB执行任务的SpringBoot程序无法注册到调度中心

标签:执行器,SpringBoot,JOB,job,任务,XXL,xxl
From: https://blog.csdn.net/m0_62128476/article/details/143891852

相关文章