分布式调度XXL-JOB急速入门

news2025/1/19 7:50:00

文章目录

        • 1.业界分布式定时任务框架简介
        • 2.分布式调度XXL-JOB核心特性
        • 3.Docker部署MySQL8.0
        • 4.XXL-JOB数据库脚本介绍
        • 5.Docker部署XXL-JOB服务端
        • 6.XXL-JOB UI菜单模块介绍
        • 7.SpringBoot整合XXL-JOB
        • 8.分布式调度参数传递
        • 9.分布式调度日志埋点
        • 10.自定义返回执行成功或失败
        • 11.XXL-Job高可用方案
        • 12.XXL-Job分片任务处理

1.业界分布式定时任务框架简介

在这里插入图片描述

  • Quartz

    • Quartz关注点在于定时任务而并非是数据,并没有一套根据数据化处理而定的流程
    • 虽然可以实现数据库作业的高可用,但是缺少了分布式的并行调度功能,相对弱点
    • 不支持任务分片、没UI界面管理,并行调度、失败策略等也缺少
  • TBSchedule

    • 这个是阿里早期开源的分布式任务调度系统,使用的是timer而不是线程池执行任务调度,使用timer在处理异常的时候是有缺陷的,但TBSchedule的作业类型比较单一,文档也缺失得比较严重
    • 目前阿里内部使用的是ScheduleX
      • 阿里云也有商业化版本: https://help.aliyun.com/product/147760.html
  • Elastic-job

    • 当当开发的分布式任务调度系统,功能强大,采用的是zookeeper实现分布式协调,具有高可用与分片。
    • 2020年6月,ElasticJob的四个子项目已经正式迁入Apache仓库
    • 由 2 个相互独立的子项目 ElasticJob-Lite 和 ElasticJob-Cloud 组成
      • ElasticJob-Lite 定位为轻量级无中心化解决方案,使用jar的形式提供分布式任务的协调服务;
      • ElasticJob-Cloud 使用 Mesos 的解决方案,额外提供资源治理、应用分发以及进程隔离等服务
    • 地址:https://shardingsphere.apache.org/elasticjob/index_zh.html
  • XXL-JOB

    • 大众点评的员工徐雪里在15年发布的分布式任务调度平台,是轻量级的分布式任务调度框架,目标是开发迅速、简单、清理、易扩展; 老版本是依赖quartz的定时任务触发,在v2.1.0版本开始 移除quartz依赖
    • 地址:https://www.xuxueli.com/xxl-job/

常规对比图

对比项XXL-JOBelastic-job
并行调度调度系统多线程并行任务分片的方式并行
弹性阔容使用Quartz基于数据库分布式功能通过zookeeper保证
高可用通过DB锁保证通过zookeeper保证
阻塞策略单机串行/丢弃后续的调度/覆盖之前的调度执行超过zookeeper的session timeout时间的话,会被清除,重新进行分片
动态分片策略以执行器为维度进行分片、支持动态的扩容平均分配/作业名hash分配/自定义策略
失败处理策略失败告警/失败重试执行完毕后主动获取未分配分片任务 服务器下线后主动寻找可以用的服务器执行任务
监控支持支持
日志支持支持

2.分布式调度XXL-JOB核心特性

(1)XXL-JOB的设计思想

  • 将调度行为抽象形成“调度中心”公共平台,而平台自身并不承担业务逻辑,“调度中心”负责发起调度请求。
  • 将任务抽象成分散的JobHandler,交由“执行器”统一管理
  • “执行器”负责接收调度请求并执行对应的JobHandler中业务逻辑。
  • 因此,“调度”和“任务”两部分可以相互解耦,提高系统整体稳定性和扩展性

(2)XXL-JOB架构图

  • 调度中心
    • 负责管理调度的信息,按照调度的配置来发出调度请求。
    • 支持可视化、简单的动态管理调度信息,包括新建、删除、更新等,这些操作都会实时生效,同时也支持监控调度结果及执行日志。
  • 执行器
    • 负责接受请求并且执行任务的逻辑。任务模块专注于任务的执行操作等等,使得开发和维护更加的简单与高效。

在这里插入图片描述

(3)XXL-JOB具有哪些特性

  • 调度中心HA(中心式):调度采用了中心式进行设计,“调度中心”支持集群部署,可保证调度中心HA
  • 执行器HA(分布式):任务分布式的执行,任务执行器支持集群部署,可保证任务执行HA
  • 触发策略:有Cron触发、固定间隔触发、固定延时触发、API事件触发、人工触发、父子任务触发
  • 路由策略:执行器在集群部署的时候提供了丰富的路由策略,如:第一个、最后一个、轮询、随机、一致性HASH、最不经常使用LFU、最久未使用LRU、故障转移等等
  • 故障转移:如果执行器集群的一台机器发生故障,会自动切换到一台正常的执行器发送任务调度
  • Rolling实时日志的监控:支持rolling方式查看输入的完整执行日志
  • 脚本任务:支持GLUE模式开发和运行脚本任务,包括Shell、python、node.js、php等等类型脚本

3.Docker部署MySQL8.0

(1)拉取Mysql镜像

docker pull mysql:latest

在这里插入图片描述

(2)启动MySQL容器

docker run -itd --name mysql-lixiang -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql
# 查看容器是否启动
docker ps 

在这里插入图片描述

(3)可视化工具连接

在这里插入图片描述
在这里插入图片描述

CREATE TABLE `xxl_job_group` (
  `id` int NOT NULL AUTO_INCREMENT,
  `app_name` varchar(64) NOT NULL COMMENT '执行器AppName',
  `title` varchar(12) NOT NULL COMMENT '执行器名称',
  `address_type` tinyint NOT NULL DEFAULT '0' COMMENT '执行器地址类型:0=自动注册、1=手动录入',
  `address_list` varchar(512) DEFAULT NULL COMMENT '执行器地址列表,多地址逗号分隔',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

CREATE TABLE `xxl_job_info` (
  `id` int NOT NULL AUTO_INCREMENT,
  `job_group` int NOT NULL COMMENT '执行器主键ID',
  `job_cron` varchar(128) NOT NULL COMMENT '任务执行CRON',
  `job_desc` varchar(255) NOT NULL,
  `add_time` datetime DEFAULT NULL,
  `update_time` datetime DEFAULT NULL,
  `author` varchar(64) DEFAULT NULL COMMENT '作者',
  `alarm_email` varchar(255) DEFAULT NULL COMMENT '报警邮件',
  `executor_route_strategy` varchar(50) DEFAULT NULL COMMENT '执行器路由策略',
  `executor_handler` varchar(255) DEFAULT NULL COMMENT '执行器任务handler',
  `executor_param` varchar(512) DEFAULT NULL COMMENT '执行器任务参数',
  `executor_block_strategy` varchar(50) DEFAULT NULL COMMENT '阻塞处理策略',
  `executor_timeout` int NOT NULL DEFAULT '0' COMMENT '任务执行超时时间,单位秒',
  `executor_fail_retry_count` int NOT NULL DEFAULT '0' COMMENT '失败重试次数',
  `glue_type` varchar(50) NOT NULL COMMENT 'GLUE类型',
  `glue_source` mediumtext COMMENT 'GLUE源代码',
  `glue_remark` varchar(128) DEFAULT NULL COMMENT 'GLUE备注',
  `glue_updatetime` datetime DEFAULT NULL COMMENT 'GLUE更新时间',
  `child_jobid` varchar(255) DEFAULT NULL COMMENT '子任务ID,多个逗号分隔',
  `trigger_status` tinyint NOT NULL DEFAULT '0' COMMENT '调度状态:0-停止,1-运行',
  `trigger_last_time` bigint NOT NULL DEFAULT '0' COMMENT '上次调度时间',
  `trigger_next_time` bigint NOT NULL DEFAULT '0' COMMENT '下次调度时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

CREATE TABLE `xxl_job_lock` (
  `lock_name` varchar(50) NOT NULL COMMENT '锁名称',
  PRIMARY KEY (`lock_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

CREATE TABLE `xxl_job_log` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `job_group` int NOT NULL COMMENT '执行器主键ID',
  `job_id` int NOT NULL COMMENT '任务,主键ID',
  `executor_address` varchar(255) DEFAULT NULL COMMENT '执行器地址,本次执行的地址',
  `executor_handler` varchar(255) DEFAULT NULL COMMENT '执行器任务handler',
  `executor_param` varchar(512) DEFAULT NULL COMMENT '执行器任务参数',
  `executor_sharding_param` varchar(20) DEFAULT NULL COMMENT '执行器任务分片参数,格式如 1/2',
  `executor_fail_retry_count` int NOT NULL DEFAULT '0' COMMENT '失败重试次数',
  `trigger_time` datetime DEFAULT NULL COMMENT '调度-时间',
  `trigger_code` int NOT NULL COMMENT '调度-结果',
  `trigger_msg` text COMMENT '调度-日志',
  `handle_time` datetime DEFAULT NULL COMMENT '执行-时间',
  `handle_code` int NOT NULL COMMENT '执行-状态',
  `handle_msg` text COMMENT '执行-日志',
  `alarm_status` tinyint NOT NULL DEFAULT '0' COMMENT '告警状态:0-默认、1-无需告警、2-告警成功、3-告警失败',
  PRIMARY KEY (`id`),
  KEY `I_trigger_time` (`trigger_time`),
  KEY `I_handle_code` (`handle_code`)
) ENGINE=InnoDB AUTO_INCREMENT=89580 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

CREATE TABLE `xxl_job_log_report` (
  `id` int NOT NULL AUTO_INCREMENT,
  `trigger_day` datetime DEFAULT NULL COMMENT '调度-时间',
  `running_count` int NOT NULL DEFAULT '0' COMMENT '运行中-日志数量',
  `suc_count` int NOT NULL DEFAULT '0' COMMENT '执行成功-日志数量',
  `fail_count` int NOT NULL DEFAULT '0' COMMENT '执行失败-日志数量',
  PRIMARY KEY (`id`),
  UNIQUE KEY `i_trigger_day` (`trigger_day`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=53 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

CREATE TABLE `xxl_job_logglue` (
  `id` int NOT NULL AUTO_INCREMENT,
  `job_id` int NOT NULL COMMENT '任务,主键ID',
  `glue_type` varchar(50) DEFAULT NULL COMMENT 'GLUE类型',
  `glue_source` mediumtext COMMENT 'GLUE源代码',
  `glue_remark` varchar(128) NOT NULL COMMENT 'GLUE备注',
  `add_time` datetime DEFAULT NULL,
  `update_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

CREATE TABLE `xxl_job_registry` (
  `id` int NOT NULL AUTO_INCREMENT,
  `registry_group` varchar(50) NOT NULL,
  `registry_key` varchar(255) NOT NULL,
  `registry_value` varchar(255) NOT NULL,
  `update_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `i_g_k_v` (`registry_group`,`registry_key`,`registry_value`)
) ENGINE=InnoDB AUTO_INCREMENT=165 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

CREATE TABLE `xxl_job_user` (
  `id` int NOT NULL AUTO_INCREMENT,
  `username` varchar(50) NOT NULL COMMENT '账号',
  `password` varchar(50) NOT NULL COMMENT '密码',
  `role` tinyint NOT NULL COMMENT '角色:0-普通用户、1-管理员',
  `permission` varchar(255) DEFAULT NULL COMMENT '权限:执行器ID列表,多个逗号分割',
  PRIMARY KEY (`id`),
  UNIQUE KEY `i_username` (`username`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

4.XXL-JOB数据库脚本介绍

  • 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:系统的用户表

5.Docker部署XXL-JOB服务端

docker run -d -e PARAMS="--spring.datasource.url=jdbc:mysql://192.168.139.200:3306/xxl_job?Unicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai \
--spring.datasource.username=root \
--spring.datasource.password=123456 \
--xxl.job.accessToken=lixiang123." \
-p 8080:8080 \
--name xxl-job-admin --restart=always xuxueli/xxl-job-admin:2.2.0

在这里插入图片描述

  • 访问xxl-job-admin可视化界面 http://ip:8080/xxl-job-admin/toLogin

在这里插入图片描述

  • 账号/密码:admin/123456

在这里插入图片描述

6.XXL-JOB UI菜单模块介绍

(1)运行报表

  • 任务数量:能够看到调度中心运行的任务数量
  • 调度次数:调度中心所触发的调度次数
  • 执行器数量:在整个调度中心中,在线的执行器数量有多少

在这里插入图片描述

(2)任务管理(配置执行任务)

  • 示例执行器:所用到的执行器
  • 任务描述:概述该任务是做什么的
  • 路由策略:
    • 第一个:选择第一个机器
    • 最后一个:选择最后一个机器
    • 轮询:依次选择执行
    • 随机:随机选择在线的机器
    • 一致性HASH:每个任务按照Hash算法固定选择某一台机器,并且所有的任务均匀散列在不同的机器上
    • 最不经常使用:使用频率最低的机器优先被使用
    • 最近最久未使用:最久未使用的机器优先被选举
    • 故障转移:按照顺序依次进行心跳检测,第一个心跳检测成功的机器选定为目标的执行器并且会发起任务调度
    • 忙碌转移:按照顺序来依次进行空闲检测,第一个空闲检测成功的机器会被选定为目标群机器,并且会发起任务调度
    • 分片广播:广播触发对于集群中的所有机器执行任务,同时会系统会自动传递分片的参数
  • Cron:执行规则
  • 调度过期策略:调度中心错过调度时间的补偿处理策略,包括:忽略、立即补偿触发一次等
  • JobHandler:定义执行器的名字
  • 阻塞处理策略:
    • 单机串行:新的调度任务在进入到执行器之后,该调度任务进入FIFO队列,并以串行的方式去进行
    • 丢弃后续调度:新的调度任务在进入到执行器之后,如果存在相同的且正在运行的调度任务,本次的调度任务请求就会被丢弃掉,并且标记为失败
    • 覆盖之前的调度:新的调度任务在进入到执行器之后,如果存在相同的且正在运行的调度任务,就会终止掉当前正在运行的调度任务,并且清空队列,运行新的调度任务。
  • 子任务ID:输入子任务的任务id,可填写多个
  • 任务超时时间:添加任务超时的时候,单位s,设置时间大于0的时候就会生效
  • 失败重试次数:设置失败重试的次数,设置时间大于0的时候就会生效
  • 负责人:填写该任务调度的负责人
  • 报警邮件:出现报警,则发送邮件

在这里插入图片描述
在这里插入图片描述

(3)执行器管理

  • 这里是配置执行器,等待执行器启动的时候都会被调度中心监听加入到地址列表

在这里插入图片描述
在这里插入图片描述

(4)调度日志

  • 这里是查看调度的日志,根据日志来查看任务具体的执行情况是怎样的

在这里插入图片描述
在这里插入图片描述

(5)用户管理

  • 对用户的一些增删改查操作

在这里插入图片描述

7.SpringBoot整合XXL-JOB

(1)新建maven项目,添加依赖

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.7</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
            <scope>compile</scope>
        </dependency>
        <!--添加xxl-job依赖-->
        <dependency>
            <groupId>com.xuxueli</groupId>
            <artifactId>xxl-job-core</artifactId>
            <version>2.3.0</version>
        </dependency>
    </dependencies>

(2)创建运行主类

/**
 * xxl-job启动类
 */
@SpringBootApplication
public class JobApplication {
    public static void main(String[] args) {
        SpringApplication.run(JobApplication.class, args);
    }
}

(3)增加logback.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false" scan="true" scanPeriod="1 seconds">

    <contextName>logback</contextName>
    <property name="log.path" value="./data/logs/xxl-job/app.log"/>

    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}.%d{yyyy-MM-dd}.zip</fileNamePattern>
        </rollingPolicy>
        <encoder>
            <pattern>%date %level [%thread] %logger{36} [%file : %line] %msg%n
            </pattern>
        </encoder>
    </appender>

    <root level="info">
        <appender-ref ref="console"/>
        <appender-ref ref="file"/>
    </root>

</configuration>

(4)增加配置文件application.properties

# 定义服务名
spring.application.name=job-server
# 定义服务端口
server.port=8081

#xxl-job配置
logging.config=classpath:logback.xml
#调度中心部署地址,多个配置逗号分隔 "http://address01,http://address02"
xxl.job.admin.addresses=http://192.168.139.200:8080/xxl-job-admin
# 执行器app名称,和控制台那边配置一样的名称,不然注册不上去
xxl.job.executor.appname=lixiang-test
# [选填]执行器注册:优先使用该配置作为注册地址,为空时使用内嵌服务 ”IP:PORT“ 作为注册地址。
# 从而更灵活的支持容器类型执行器动态IP和动态映射端口问题。
xxl.job.executor.address=

xxl.job.accessToken=lixiang123.

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

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

#执行器日志文件存储路径,需要对该路径拥有读写权限;为空则使用默认路径
xxl.job.executor.logpath=./data/logs/xxl-job/executor

#执行器日志保存天数
xxl.job.executor.logretentiondays=30

在这里插入图片描述

(5)增加XxlJobConfig配置类

@Configuration
public class XxlJobConfig {

    /**
     * 定义Logger
     */
    private final Logger log = 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;

    public XxlJobConfig() {
    }

    /**
     * 配置xxl-job
     * @return
     */
    @Bean
    public XxlJobSpringExecutor xxlJobExecutor() {
        log.info("xxl-job config init");
        XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
        xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
        xxlJobSpringExecutor.setAppname(appName);
        xxlJobSpringExecutor.setIp(ip);
        xxlJobSpringExecutor.setPort(port);
        xxlJobSpringExecutor.setAccessToken(accessToken);
        xxlJobSpringExecutor.setLogPath(logPath);
        xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
        return xxlJobSpringExecutor;
    }
}

(6)启动验证

在这里插入图片描述

(7)创建xxl-job定时任务

/**
 * 测试Job
 */
@Component
public class TestJob {

    private final Logger log = LoggerFactory.getLogger(TestJob.class);

    @XxlJob(value = "TestJob",init = "init",destroy = "destroy")
    public ReturnT<String> execute(String param){
        log.info("TestJob execute 任务方法触发成功");
        return ReturnT.SUCCESS;
    }

    private void init(){
        log.info("执行 TestJob init >>>>>");
    }

    private void destroy(){
        log.info("执行 TestJob destroy >>>>>");
    }
}

(8)xxl-job ui配置任务

在这里插入图片描述

(9)运行JOB,启动SpringBoot项目

在这里插入图片描述
在这里插入图片描述

(10)路由策略种类

  • 第一个:当选择该策略时,会选择执行器注册地址的第一台机器执行,如果第一台机器出现故障,则调度任务失败。

  • 最后一个:当选择该策略时,会选择执行器注册地址的最后一台机器执行,如果最后一台机器出现故障,则调度任务失败。

  • 轮询:当选择该策略时,会按照执行器注册地址轮询分配任务,如果其中一台机器出现故障,调度任务失败,任务不会转移。

  • 随机:当选择该策略时,会按照执行器注册地址随机分配任务,如果其中一台机器出现故障,调度任务失败,任务不会转移。

  • 一致性HASH:当选择该策略时,每个任务按照Hash算法固定选择某一台机器。如果那台机器出现故障,调度任务失败,任务不会转移。

  • 最不经常使用:当选择该策略时,会优先选择使用频率最低的那台机器,如果其中一台机器出现故障,调度任务失败,任务不会转移。

  • 最近最久未使用:当选择该策略时,会优先选择最久未使用的机器,如果其中一台机器出现故障,调度任务失败,任务不会转移。

  • 故障转移:当选择该策略时,按照顺序依次进行心跳检测,如果其中一台机器出现故障,则会转移到下一个执行器,若心跳检测成功,会选定为目标执行器并发起调度。

  • 忙碌转移:当选择该策略时,按照顺序依次进行空闲检测,如果其中一台机器出现故障,则会转移到下一个执行器,若空闲检测成功,会选定为目标执行器并发起调度。

  • 分片广播:当选择该策略时,广播触发对应集群中所有机器执行一次任务,同时系统自动传递分片参数;可根据分片参数开发分片任务。如果其中一台机器出现故障,则该执行器执行失败,不会影响其他执行器。

8.分布式调度参数传递

(1)在UI上传递参数

在这里插入图片描述

(2)代码中修改

String jobParam = XxlJobHelper.getJobParam();

在这里插入图片描述

(3)接收JSON

在这里插入图片描述
在这里插入图片描述

9.分布式调度日志埋点

在这里插入图片描述

(1)代码配置

  XxlJobHelper.log("我是业务埋点日志,方便查询错误");

在这里插入图片描述
在这里插入图片描述

10.自定义返回执行成功或失败

  • 默认任务结果为 “成功” 状态,不需要主动设置
  • 自主设置任务结果(会出现在【执行备注】里面)
    • 如想设置任务结果为失败,可以通过 "XxlJobHelper.handleFail
    • 如想设置任务结果为成功,handleSuccess
@XxlJob(value = "TestJob",init = "init",destroy = "destroy")
    public void execute(){
        log.info("TestJob execute 任务方法触发成功");
        String jobParam = XxlJobHelper.getJobParam();
        log.info("TestJob 接收到的参数:{}",jobParam);
        XxlJobHelper.log("我是业务埋点日志,方便查询错误");
        if("测试成功".equals(jobParam)){
            XxlJobHelper.handleSuccess();
        }else if("测试失败".equals(jobParam)){
            XxlJobHelper.handleFail();
        }
    }

在这里插入图片描述

11.XXL-Job高可用方案

  • HA/集群

    • 为了避免单点故障,任务调度系统通常需要通过集群实现系统高可用

    • 由于任务调度系统的特殊性,“调度”和“任务”两个模块需要均支持集群部署,由于职责不同,因此各自集群侧重点也有有所不同。

    • 调度中心集群

      • 目标为避免调度模块单点故障,集群节点需要通过锁或命名服务保证单个任务的单次触发,只在其中一个节点上生效,以防止任务的重复触发。
    • 执行器集群

      • 目标为避免任务模块单点故障,进一步可以通过自定义路由策略实现Failover等高级功能,从而在执行器某台机器节点故障时自动转移不会影响到任务的正常触发执行
  • 高可用集群架构
    在这里插入图片描述

  • 执行器配置调度中心集群

#调度中心部署地址,多个配置逗号分隔 "http://address01,http://address02"
xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin,http://127.0.0.1:8079/xxl-job-admin

12.XXL-Job分片任务处理

(1)什么是分片任务

  • 执行器集群部署,如果任务的路由策略选择【分片广播】,一次任务调度将会【广播触发】对应集群中所有执行器执行一次任务,同时系统自动传递分片参数,执行器可根据分片参数开发分片任务
  • 需要处理的海量数据,以执行器为划分,每个执行器分配一定的任务数,并行执行
  • XXL-Job支持动态扩容执行器集群,从而动态增加分片数量,到达更快处理任务
  • 分片的值是调度中心分配的

在这里插入图片描述

(2)案例

  • 模拟100个用户数据执行定时,分片处理
/**
 * 测试Job
 */
@Component
public class ShardingJob {

    private final Logger log = LoggerFactory.getLogger(ShardingJob.class);

    @XxlJob(value = "shardingJob")
    public void execute(){
        log.info("shardingJob execute 任务方法触发成功");
        // 当前分片数,从0开始,即执行器的序号
        int shardIndex = XxlJobHelper.getShardIndex();
        //总分片数,执行器集群总机器数量
        int shardTotal = XxlJobHelper.getShardTotal();
        // 业务逻辑
        List<Integer> allUserIds = getAllUserIds();
        allUserIds.forEach(obj -> {
            if (obj % shardTotal == shardIndex) {
                log.info("第 {} 片, 命中分片开始处理用户id={}",shardIndex,obj);
            }
        });
    }
    private List<Integer> getAllUserIds() {
        List<Integer> ids = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            ids.add(i);
        }
        return ids;
    }

}

在这里插入图片描述
在这里插入图片描述

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

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

相关文章

C#上位机基础学习_基于SOCKET实现与PLC服务器的TCP通信(二)

C#上位机基础学习_基于SOCKET实现与PLC服务器的TCP通信(二) 测试软件: TIA PORTAL V15.1 S7-PLCSIM ADVANCED V3.0 Visual Studio 2019 在上次的分享中,我们了解了TIA博途一侧的具体组态配置,具体内容可参考以下链接中的内容: C#上位机基础学习_基于SOCKET实现与PLC服务…

【ROS】—— 机器人系统仿真 —URDF优化_xacro (十四)

文章目录前言1. URDF优化_xacro2. Xacro_快速体验3. Xacro_语法详解3.1 属性与算数运算3.2 宏3.3 文件包含4. Xacro_完整使用流程示例4.1 编写 Xacro 文件4.2 集成launch文件5. Xacro_实操前言 &#x1f4e2;本系列将依托赵虚左老师的ROS课程&#xff0c;写下自己的一些心得与笔…

SpringBoot自动配置原理

1、自动配置原理 1、我们编写的SpringBoot启动类上有一个SpringBootApplication注解&#xff0c;表示当前类是springboot的启动类(入口类)。 package com.baidou;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBo…

微信小程序2.9.0基础库canvas2D新API,生成海报保存到手机功能实现

canvasToTempFilePath的官方文档写着在 draw()回调里调用该方法才能保证图片导出成功。文档地址&#xff1a;wx.canvasToTempFilePath(Object object, Object this) | 微信开放文档 我在这里面使用的canva 获取canvas实例&#xff0c;使用的官方的代码。用一个变量canvas保存实…

聊聊 AI 平台存储方案和选型

最近火爆全网的 ChatGPT 再次带来一股 AI 热潮。 过去的五年&#xff0c;AI 快速发展并应用到很多领域中。作为一家存储企业&#xff0c;我们也感受到了 AI 行业的活力&#xff0c;和我们交流团队中&#xff0c;AI 企业越来越多&#xff0c;有自动驾驶、蛋白质结构预测、量化投…

【HTML】【消失的花木兰】花木兰:三兔蹦迪走,安能辨我是兔子?

前言 &#xff08;改编&#xff09;  某日&#xff0c;参军后的花木兰刚回到家乡&#xff0c;却不料遇上抓拿自己的官兵… 因此&#xff0c;花木兰变成兔子躲了起来&#xff0c;你能否找到躲起来的花木兰呢&#xff1f;一起来拭目以待… 一、游戏名称与游戏规则&#xff08…

joinquant量化数据精准吗?

在股票量化投资中&#xff0c;joinquant量化数据起到很大的作用&#xff0c;因为joinquant量化平台的数据能够从众多只股票数据中&#xff0c;能够一一罗列出来&#xff0c;也就是说&#xff0c;joinquant量化数据可以在计算和分析数据模型中&#xff0c;能够帮助投资者找到他们…

【SpringBoot1】创建第一个SpringBoot项目

创建SpringBoot项目可以通过两种方式&#xff1a; 1、通过访问&#xff1a;https://start.spring.io/&#xff0c;SpringBoot的官方网站进行创建SpringBoot项目&#xff1b; 2、通过工具&#xff08;例如&#xff1a;Idea&#xff09;创建SpringBoot项目。本次使用IDEA创建第一…

数据结构进阶 红黑树

作者&#xff1a;小萌新 专栏&#xff1a;数据结构进阶 作者简介&#xff1a;大二学生 希望能和大家一起进步&#xff01; 本篇博客简介&#xff1a;介绍高阶数据结构: 红黑树 红黑树红黑树的概念红黑树的性质红黑树节点的定义红黑树的插入情况一情况二情况三红黑树的验证红黑…

远程监控网络摄像头通用指南

一、引言 随着物联网技术的发展&#xff0c;越来越多的场景需要我们通过技术手段去感知。画面和声音相当于机器的眼睛和耳朵&#xff0c;有了这些实时数据我们可以做很多事情&#xff0c;比如车牌识别、人脸识别、体温识别等等。本文将全方位介绍网络摄像头如何接入软件的实现…

2022.12 青少年机器人技术等级考试理论综合试卷(四级)

2022年12月 青少年机器人技术等级考试理论综合试卷&#xff08;四级&#xff09; 分数&#xff1a; 100 题数&#xff1a; 30 一、 单选题(共 20 题&#xff0c; 共 80 分) 1.以下关于 Arduino C 语言的说法&#xff0c; 正确的是?&#xff08; &#xff09; A.setup() 函数和…

SpringMVC Interceptor拦截器

SpringMVC中的拦截器用于拦截控制器方法的执行&#xff0c;执行在Controller前后&#xff0c;和视图渲染完成后。如下图所示&#xff1a; 一、创建拦截器 继承HandlerInterceptor 接口&#xff0c;并实现其中的方法 public class FirstInterceptor implements HandlerInter…

儿子小伟刚刚再婚,大衣哥就河南新乡商演,这是给孙子攒奶粉钱吗

现如今的社会&#xff0c;因为人们的攀比心理&#xff0c;结一次婚能让人脱一层皮&#xff0c;尤其是农村赚钱难&#xff0c;结婚花钱就更难了。其实不只是普通老百姓&#xff0c;强如农民歌唱家大衣哥这样的人&#xff0c;也架不住儿子一而再&#xff0c;再而三的结婚。 大衣哥…

Qt基础之二十一:QtRO(Qt Remote Object)实现进程间通信

这里将QtRO单独从上一篇Qt基础之二十:进程间通信拎出来,因为它是Qt5.9以后新加入的模块,专门用于进程间通信。其使用步骤有点类似之前介绍过的RPC(Remote Procedure Call)框架:gRPC和thrift,关于这两个框架详见 Qt中调用thrift和Qt中调用gRPC QtRO基于Socket封装,不仅支…

小程序开发——模板与配置

一、WXML 模板语法 1.数据绑定的基本原则 ① 在 data 中定义数据 ② 在 WXML 中使用数据2.在 data 中定义页面的数据 在页面对应的 .js 文件中&#xff0c;把数据定义到 data 对象中即可&#xff1a;3. Mustache 语法的格式 把data中的数据绑定到页面中渲染&#xff0c;使用…

【测试】java+selenium环境搭建

努力经营当下&#xff0c;直至未来明朗&#xff01; 文章目录一、下载安装谷歌浏览器二、下载谷歌驱动三、常见问题&解决方法1. SessionNotCreatedException2. The version of ChromeDriver only support xxxxxxxxx3. The path to the driver executable the path to普通小…

5-2输入/输出管理-I/O核心子系统

文章目录一.I/O调度二.设备保护三.SPOOLing技术&#xff08;假脱机技术&#xff09;四.设备的分配与回收1.设备分配时应该考虑的因素2.静态分配和动态分配3.设备分配管理中的数据结构&#xff08;1&#xff09;设备控制表DCT&#xff08;Device Control Table&#xff09;&…

MySQL进阶篇之Linux安装MySQL8.0.26

Linux安装MySQL 需要更多安装MySQL的教程&#xff0c;请查阅Linux学习笔记——MySQL数据库管理系统安装部署 1、MySQL下载地址&#xff1a;https://downloads.mysql.com/archives/community/ 2、在FinalShell中输入rz&#xff0c;然后选择下载好的MySQL安装包&#xff0c;进行上…

【数据质量】一起聊聊数据质量

Garbage In, Garbage Out ​ 数据质量关注的是数据的健康&#xff0c;数据健康和人的健康很相似&#xff0c;人的健康会影响人的生活品质&#xff0c;同样数据的健康会影响数据的使用品质。为了保证我们健康&#xff0c;我们需要养成良好的生活习惯&#xff0c;膳食平衡&#x…

Open3D DBSCAN聚类(Python版本)

文章目录 一、简介二、算法步骤三、实现代码四、实现效果参考资料一、简介 DBSCAN算法,全称为“Density-Based Spatial Clustering of Applications with Node”,也就是“基于密度的聚类”。此类算法是假设聚类结构能通过样本分布的紧密程度确定,从样本密度的角度来考察样本…