XXL-JOB实践:从零开始构建你的任务调度系统

2024-09-06 19:52

本文主要是介绍XXL-JOB实践:从零开始构建你的任务调度系统,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 一、序言
    • 1、系统组成
    • 2、架构图
  • 二、部署调度中心
    • 1、下载源码
    • 2、执行数据库脚本
    • 3、修改application.properties配置文件
    • 4、启动调度中心
  • 三、部署执行器
    • 1、引入依赖
    • 2、执行器配置
      • 2.1 XxlJobProperties属性文件
      • 2.2 XxlJobConfig配置类
      • 2.3 XxlJobHanlder作业处理器
      • 2.4 application.yml
    • 3、启动执行器
  • 四、调度示例
    • 1、添加执行器
    • 2、添加任务
    • 3、调度测试

一、序言

XXL-JOB是一个分布式任务调度平台,部署方便,使用简单,开箱即用,目前已经有600多家公司线上已经接入。

1、系统组成

XXL-JOB主要由两个模块组成,一个是调度中心,一个是执行器。

  • 调度模块(调度中心)
    负责管理调度信息,按照调度配置发出调度请求,自身不承担业务代码。调度系统与任务解耦,提高了系统可用性和稳定性,同时调度系统性能不再受限于任务模块。

  • 执行模块(执行器)
    负责接收调度请求并执行任务逻辑。任务模块专注于任务的执行等操作,开发和维护更加简单和高效。

2、架构图

主要特性如下:.

  • 调度中心与执行器通过自研RPC进行通讯和调度。
  • 调度中心多线程调度可以避免IO阻塞,支持并行调度
  • 多个执行器支持故障转移(Failover)执行器。
  • 调度中心都支持集群部署,提高系统可用性(HA)。
  • 支持调度过期处理 (如:服务重启,调度线程耗尽,上次调度持续阻塞导致下次调度过期)。
  • 支持调度日志查看。

在这里插入图片描述


二、部署调度中心

调度中心的部署非常简单,开箱即用,详细说明参考:官方文档。

1、下载源码

建议下载最新的Release版本,我用的版本是2.4.1

2、执行数据库脚本

项目目录下有调度中心依赖的数据库表:doc/db/tables_xxl_job.sql,直接执行即可,如下:

#
# XXL-JOB v2.4.1
# Copyright (c) 2015-present, xuxueli.CREATE TABLE `xxl_job_info`
(`id`                        int(11) NOT NULL AUTO_INCREMENT,`job_group`                 int(11) NOT NULL COMMENT '执行器主键ID',`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 '报警邮件',`schedule_type`             varchar(50)  NOT NULL DEFAULT 'NONE' COMMENT '调度类型',`schedule_conf`             varchar(128)          DEFAULT NULL COMMENT '调度配置,值含义取决于调度类型',`misfire_strategy`          varchar(50)  NOT NULL DEFAULT 'DO_NOTHING' 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(11) NOT NULL DEFAULT '0' COMMENT '任务执行超时时间,单位秒',`executor_fail_retry_count` int(11) 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(4) NOT NULL DEFAULT '0' COMMENT '调度状态:0-停止,1-运行',`trigger_last_time`         bigint(13) NOT NULL DEFAULT '0' COMMENT '上次调度时间',`trigger_next_time`         bigint(13) NOT NULL DEFAULT '0' COMMENT '下次调度时间',PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;CREATE TABLE `xxl_job_log`
(`id`                        bigint(20) NOT NULL AUTO_INCREMENT,`job_group`                 int(11) NOT NULL COMMENT '执行器主键ID',`job_id`                    int(11) 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(11) NOT NULL DEFAULT '0' COMMENT '失败重试次数',`trigger_time`              datetime     DEFAULT NULL COMMENT '调度-时间',`trigger_code`              int(11) NOT NULL COMMENT '调度-结果',`trigger_msg`               text COMMENT '调度-日志',`handle_time`               datetime     DEFAULT NULL COMMENT '执行-时间',`handle_code`               int(11) NOT NULL COMMENT '执行-状态',`handle_msg`                text COMMENT '执行-日志',`alarm_status`              tinyint(4) 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 DEFAULT CHARSET=utf8mb4;CREATE TABLE `xxl_job_log_report`
(`id`            int(11) NOT NULL AUTO_INCREMENT,`trigger_day`   datetime DEFAULT NULL COMMENT '调度-时间',`running_count` int(11) NOT NULL DEFAULT '0' COMMENT '运行中-日志数量',`suc_count`     int(11) NOT NULL DEFAULT '0' COMMENT '执行成功-日志数量',`fail_count`    int(11) NOT NULL DEFAULT '0' COMMENT '执行失败-日志数量',`update_time`   datetime DEFAULT NULL,PRIMARY KEY (`id`),UNIQUE KEY `i_trigger_day` (`trigger_day`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;CREATE TABLE `xxl_job_logglue`
(`id`          int(11) NOT NULL AUTO_INCREMENT,`job_id`      int(11) 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;CREATE TABLE `xxl_job_registry`
(`id`             int(11) 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 DEFAULT CHARSET=utf8mb4;CREATE TABLE `xxl_job_group`
(`id`           int(11) NOT NULL AUTO_INCREMENT,`app_name`     varchar(64) NOT NULL COMMENT '执行器AppName',`title`        varchar(12) NOT NULL COMMENT '执行器名称',`address_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '执行器地址类型:0=自动注册、1=手动录入',`address_list` text COMMENT '执行器地址列表,多地址逗号分隔',`update_time`  datetime DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;CREATE TABLE `xxl_job_user`
(`id`         int(11) NOT NULL AUTO_INCREMENT,`username`   varchar(50) NOT NULL COMMENT '账号',`password`   varchar(50) NOT NULL COMMENT '密码',`role`       tinyint(4) NOT NULL COMMENT '角色:0-普通用户、1-管理员',`permission` varchar(255) DEFAULT NULL COMMENT '权限:执行器ID列表,多个逗号分割',PRIMARY KEY (`id`),UNIQUE KEY `i_username` (`username`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;CREATE TABLE `xxl_job_lock`
(`lock_name` varchar(50) NOT NULL COMMENT '锁名称',PRIMARY KEY (`lock_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;INSERT INTO `xxl_job_user`(`id`, `username`, `password`, `role`, `permission`) VALUES (1, 'admin', 'e10adc3949ba59abbe56e057f20f883e', 1, NULL);
INSERT INTO `xxl_job_lock` ( `lock_name`) VALUES ( 'schedule_lock');

3、修改application.properties配置文件

直接修改数据源配置即可,下面的xxl.job.accessToken配置为执行器与调度中心通讯的访问token,为可选配置。

在这里插入图片描述

4、启动调度中心

直接启动,浏览器输入http://localhost:8888/xxl-job-admin进入登录页面,默认用户名/密码admin/123456

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


三、部署执行器

1、引入依赖

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

2、执行器配置

2.1 XxlJobProperties属性文件

@Data
@ConfigurationProperties(prefix = "xxl.job")
public class XxlJobProperties {/*** 执行器通讯TOKEN [选填]:非空时启用,需要与调度中心的保持一致*/private String accessToken;/*** 调度中心信息*/private Admin admin;/*** 执行器信息*/private Executor executor;@Datapublic static class Admin {/*** 调度中心部署跟地址,如调度中心集群部署存在多个地址则用逗号分隔。执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调";为空则关闭自动注册*/private String addresses;}@Datapublic static class Executor {/*** 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册*/private String appName;/*** 执行器注册 [选填]:优先使用该配置作为注册地址,为空时使用内嵌服务 ”IP:PORT“ 作为注册地址。从而更灵活的支持容器类型执行器动态IP和动态映射端口问题*/private String address;/*** 执行器IP [选填]:默认为空表示自动获取IP,多网卡时可手动设置指定IP,该IP不会绑定Host仅作为通讯实用;地址信息用于 "执行器注册" 和 "调度中心请求并触发任务"*/private String ip;/*** 执行器端口号 [选填]:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口*/private Integer port;/*** 执行器运行日志文件存储磁盘路径 [选填] :zz需要对该路径拥有读写权限;为空则使用默认路径*/private String logPath;/*** 执行器日志文件保存天数 [选填] : 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能*/private Integer logRetentionDays;}
}

2.2 XxlJobConfig配置类

@Configuration
@EnableConfigurationProperties(XxlJobProperties.class)
public class XxlJobConfig {@Beanpublic XxlJobSpringExecutor xxlJobSpringExecutor(XxlJobProperties xxlJobProperties) {XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();xxlJobSpringExecutor.setAdminAddresses(xxlJobProperties.getAdmin().getAddresses());Executor executor = xxlJobProperties.getExecutor();xxlJobSpringExecutor.setAppname(executor.getAppName());xxlJobSpringExecutor.setAddress(executor.getAddress());xxlJobSpringExecutor.setIp(executor.getIp());xxlJobSpringExecutor.setPort(executor.getPort());xxlJobSpringExecutor.setLogPath(executor.getLogPath());xxlJobSpringExecutor.setLogRetentionDays(executor.getLogRetentionDays());xxlJobSpringExecutor.setAccessToken(xxlJobProperties.getAccessToken());return xxlJobSpringExecutor;}
}

2.3 XxlJobHanlder作业处理器

@Slf4j
@Component
public class XxlJobHanlder {@XxlJob("simpleJobHanlder")public void simpleJobHanlder() {log.info("Hello World!");// 可通过该工具类指定任务是否处理成功或者失败:XxlJobHelper.handleSuccess()或者XxlJobHelper.handleFail()XxlJobHelper.handleSuccess();}@XxlJob("paramJobHanlder")public void paramJobHanlder() {String jobParam = XxlJobHelper.getJobParam();log.info("paramJobHandler is executing, job param:{}, msg: Hello World! ",jobParam);XxlJobHelper.handleSuccess();}@XxlJob("shardingJobHandler")public void shardingJobHandler() {// 分片序号,即执行器编号int shardIndex = XxlJobHelper.getShardIndex();// 总分片数int sharTotal = XxlJobHelper.getShardTotal();log.info("分片参数:当前分片序号:{},总分片数:{}", shardIndex, sharTotal);// 模拟任务超时LockSupport.parkNanos(1000 * 1000 * 1000 * 5L);log.info("分片执行完毕");XxlJobHelper.handleSuccess();}

上面我们定义了3个作业处理器,分别是简单作业处理器带作业参数的作业处理器分片作业处理器

XxlJobHelper工具类提供了一些基本方法,比如指定任务调度为成功或者失败,获取作业和分片参数等。

2.4 application.yml

spring:application:name: xxl-job-executor
server:port: 8081
xxl:job:# 执行器通讯TOKEN [选填]:非空时启用accessToken: rXXZnXk8fsx8RIOtjLUT5koi4hzCMS0Dadmin:# 调度中心部署跟地址 [选填]:如调度中心集群部署存在多个地址则用逗号分隔。执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调";为空则关闭自动注册addresses: http://localhost:8888/xxl-job-adminexecutor:# 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册app-name: xxl-job-executor# 执行器运行日志文件存储磁盘路径 [选填] :zz需要对该路径拥有读写权限;为空则使用默认路径log-path: logs/jobhandler# 执行器日志文件保存天数 [选填] : 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能log-retention-days: 30# 执行器端口号 [选填]:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口port: 9999# 执行器注册 [选填]:优先使用该配置作为注册地址,为空时使用内嵌服务 ”IP:PORT“ 作为注册地址。从而更灵活的支持容器类型执行器动态IP和动态映射端口问题address:# 执行器IP [选填]:默认为空表示自动获取IP,多网卡时可手动设置指定IP,该IP不会绑定Host仅作为通讯实用;地址信息用于 "执行器注册" 和 "调度中心请求并触发任务"ip:

备注:

  • xxl.job.accessToken的值必须与调度中心配置的token保持一致,不然会连不上调度中心。
  • xxl.job.executor.app-name的值为执行器名称,如果是自动注册,在控制台添加执行器时,需与该值保持一致。
    xxl.job.executor.port为执行器暴露的端口,调度中心将会通过该端口与执行器进行RPC调度。

3、启动执行器

启动执行器后,我们会发现三个作业处理器注册成功,并且执行器启动了内置服务器,并暴露9999端口与调度中心通讯。

在这里插入图片描述


四、调度示例

1、添加执行器

在控制台执行器管理中我们需要手动添加执行器,这里的AppName一定要与执行器xxl.job.executor.app-name的值一致,不然自动注册会失败。

在这里插入图片描述

注册成功后我们可以看到执行器的地址和端口,如下:

在这里插入图片描述

2、添加任务

在控制台任务管理中可以直接新增任务,如下:

在这里插入图片描述
这里我们添加了两个任务,可以点击操作中的执行一次进行调度测试。

在这里插入图片描述

3、调度测试

(1) simpleJobHanlder测试

17:32:47.089 [xxl-job, EmbedServer bizThreadPool-626635208] INFO  c.x.job.core.executor.XxlJobExecutor - >>>>>>>>>>> xxl-job regist JobThread success, jobId:2, handler:com.xxl.job.core.handler.impl.MethodJobHandler@116a2108[class com.universe.jobhanlder.XxlJobHanlder#simpleJobHanlder]
17:32:47.091 [xxl-job, JobThread-2-1725615167089] INFO  c.universe.jobhanlder.XxlJobHanlder - Hello World!

(2) paramJobHanlder测试

在这里插入图片描述
这里我们是带了作业参数的,调度结果如下:

17:35:26.556 [xxl-job, EmbedServer bizThreadPool-412218852] INFO  c.x.job.core.executor.XxlJobExecutor - >>>>>>>>>>> xxl-job regist JobThread success, jobId:3, handler:com.xxl.job.core.handler.impl.MethodJobHandler@5e8c34a0[class com.universe.jobhanlder.XxlJobHanlder#paramJobHanlder]
17:35:26.558 [xxl-job, JobThread-3-1725615326556] INFO  c.universe.jobhanlder.XxlJobHanlder - paramJobHandler is executing, job param:{"name": "Nick"
}, msg: Hello World! 

在这里插入图片描述

这篇关于XXL-JOB实践:从零开始构建你的任务调度系统的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1142962

相关文章

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

基于人工智能的图像分类系统

目录 引言项目背景环境准备 硬件要求软件安装与配置系统设计 系统架构关键技术代码示例 数据预处理模型训练模型预测应用场景结论 1. 引言 图像分类是计算机视觉中的一个重要任务,目标是自动识别图像中的对象类别。通过卷积神经网络(CNN)等深度学习技术,我们可以构建高效的图像分类系统,广泛应用于自动驾驶、医疗影像诊断、监控分析等领域。本文将介绍如何构建一个基于人工智能的图像分类系统,包括环境

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

Retrieval-based-Voice-Conversion-WebUI模型构建指南

一、模型介绍 Retrieval-based-Voice-Conversion-WebUI(简称 RVC)模型是一个基于 VITS(Variational Inference with adversarial learning for end-to-end Text-to-Speech)的简单易用的语音转换框架。 具有以下特点 简单易用:RVC 模型通过简单易用的网页界面,使得用户无需深入了

【区块链 + 人才服务】可信教育区块链治理系统 | FISCO BCOS应用案例

伴随着区块链技术的不断完善,其在教育信息化中的应用也在持续发展。利用区块链数据共识、不可篡改的特性, 将与教育相关的数据要素在区块链上进行存证确权,在确保数据可信的前提下,促进教育的公平、透明、开放,为教育教学质量提升赋能,实现教育数据的安全共享、高等教育体系的智慧治理。 可信教育区块链治理系统的顶层治理架构由教育部、高校、企业、学生等多方角色共同参与建设、维护,支撑教育资源共享、教学质量评估、

软考系统规划与管理师考试证书含金量高吗?

2024年软考系统规划与管理师考试报名时间节点: 报名时间:2024年上半年软考将于3月中旬陆续开始报名 考试时间:上半年5月25日到28日,下半年11月9日到12日 分数线:所有科目成绩均须达到45分以上(包括45分)方可通过考试 成绩查询:可在“中国计算机技术职业资格网”上查询软考成绩 出成绩时间:预计在11月左右 证书领取时间:一般在考试成绩公布后3~4个月,各地领取时间有所不同

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识