当前位置: 首页 > news >正文

xxl-job 分布式调度开源系统

什么是xxl-job

xxl-job 项目是分布式调度开源系统,具有开发迅速、学习简单、轻量级、易扩展等核心设计目标。

安装xxl-job

获取源码

git clone git@github.com:xuxueli/xxl-job.git

构建工程

进入工程目录,使用mvn命令构建工程:

cd xxl-job mvn package

构建过程中,会下载所需要的jar包。

修改配置文件

​在IDEA中打开工程,需要修改logback.xml和properties中的日志路径。具体修改方法可以参考XXL-JOB的官方文档。

初始化数据库

运行以下命令初始化数据库

source /xxl-job/doc/db/tables_xxl_job.sql

同时,需要修改application.properties中的数据库用户密码。具体修改方法可以参考XXL-JOB的官方文档。

运行web工程

在IDEA中运行web工程,访问地址为:http://localhost:8080/xxl-job-adm。
以上是XXL-JOB的安装和配置过程。在实际应用中,还需要根据具体需求进行进一步的配置和优化。同时,建议参考XXL-JOB的官方文档和社区资源,以便更好地了解和使用XXL-JOB平台。

其他项目引入XXL-JOB

导入依赖,配置执行器

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

配置文件配置

xxl: job: admin: addresses: http://localhost:8080/xxl-job-admin executor: appname: bill #执行器名字(很重要,在调度中心要用到) address: ip: port: 9999 #执行器端口号 logpath: /data/applogs/xxl-job/jobhandler logretentiondays: 30 accessToken: default_token

主要就是xxl.job.admin.addressesxxl.job.executor.appname这俩,第一个必须指向正确的调度中心地址。修改xxl-job-admin配置文件application.properties中xxl.job.accessToken的token值,默认值为default_token

后台配置执行器

配置xxl-job的配置类

package com.hworld.custom.config; import com.xxl.job.core.executor.impl.XxlJobSpringExecutor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; /** * <p> * xxl-job 配置类 通过配置 xxl.job.enabled 控制是否启用XXL-JOB功能 * </p> * * @author : hudy * @date : 2023/11/20 */ @Configuration @Slf4j @ConditionalOnProperty(name = "xxl.job.enabled", havingValue = "true", matchIfMissing = false) public class XxlJobConfig { @Value("${xxl.job.admin.addresses}") private String adminAddresses; @Value("${xxl.job.executor.appname}") private String appName; @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 @Profile({"local", "prod"}) public XxlJobSpringExecutor xxlJobExecutor() { log.info(">>>>>>>>>>> xxl-job config init."); XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor(); xxlJobSpringExecutor.setAdminAddresses(adminAddresses); xxlJobSpringExecutor.setAppname(appName); xxlJobSpringExecutor.setPort(port); xxlJobSpringExecutor.setAccessToken(accessToken); xxlJobSpringExecutor.setLogPath(logPath); xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays); return xxlJobSpringExecutor; } }

项目配置正确,服务自动注册会将项目地址自动注册到Online机器地址。并且其他项目服务日志有

这样就是直接使用@XxlJob注解了

关于XXL-JOB

一、基本组成

XXL-JOB主要由调度中心和执行器两部分组成:

  • 调度中心:统一管理任务调度平台上的调度任务,负责触发调度执行,并且提供任务管理平台。它主要负责管理调度信息,按照调度配置发出调度请求,但自身不承担业务代码。
  • 执行器:接收调度中心的调度并且执行,可以直接执行也可以集成到项目中。它负责接收调度请求并执行任务逻辑,包括执行请求、终止请求和日志请求等。

二、特点与优势

  • 简单易用:XXL-JOB提供了友好的Web界面,支持通过Web界面进行任务的增删改查,同时也支持通过API接口进行任务管理。用户可以通过简单的操作完成任务的调度和管理。
  • 动态管理:支持动态修改任务状态、启动/停止任务以及终止运行中任务,所有操作都会实时生效。
  • 高可用性:调度中心和执行器都支持集群部署,可保证调度和执行的高可用性。即使某个节点出现故障,也能自动切换到其他节点继续执行任务。
  • 弹性扩容缩容:一旦有新执行器机器上线或者下线,下次调度时将会重新分配任务,实现弹性扩容缩容。
  • 丰富的路由策略:执行器集群部署时提供多种路由策略,包括第一个、最后一个、轮询、随机、一致性HASH等,以满足不同场景下的需求。
  • 故障转移:如果执行器集群中某一台机器故障,将会自动Failover切换到一台正常的执行器发送调度请求,确保任务能够正常执行。
  • 执行失败查看日志:对于执行失败的任务,可以查看详细的日志信息,方便用户进行问题排查和修复。
  • 支持邮件报警:当任务执行失败时,XXL-JOB支持发送邮件通知相关人员,以便及时处理异常情况。

三、应用场景

XXL-JOB适用于各种需要定时执行任务或实时处理任务的场景,如:

  • 定时发送邮件:通过XXL-JOB可以定时发送邮件通知相关人员。
  • 定时生成报表:可以定时生成各类业务报表,供相关人员进行分析和决策。
  • 定时清理数据:可以定时清理过期或无效的数据,确保数据库的整洁和高效运行。
  • 实时数据采集:可以实时采集各类业务数据,并进行处理和分析。
  • 实时消息推送:可以实时推送各类业务消息给用户或第三方系统。

四、与其他任务调度框架的比较

与Quartz等传统的任务调度框架相比,XXL-JOB具有以下优势:

  • 学习成本低:XXL-JOB提供了可视化的Web界面和丰富的文档支持,降低了学习成本。
  • 操作简便:通过Web界面可以方便地进行任务的创建、编辑、删除和查询等操作。
  • 负载均衡:XXL-JOB通过执行器实现协同分配式运行任务,充分发挥集群优势,实现了负载均衡。

xxl-job如何获取参数:

通过任务参数字段

在XXL-JOB的任务管理界面,每个任务都有一个“任务参数”字段。你可以在这个字段中填写需要传递给执行器的参数。这些参数通常以JSON、键值对或其他格式编写,具体取决于你的执行器如何解析这些参数JobHandler任务方法名填写@XxlJob注解中的名称

XxlJobHelper主要API说明

  • XxlJobHelper.getJobParam(): 获取任务参数
  • XxlJobHelper.getShardIndex(): 获取当前分片序号
  • XxlJobHelper.getShardTotal(): 获取总分片数
  • XxlJobHelper.handleSuccess(): 标记任务执行成功
  • XxlJobHelper.handleFail(): 标记任务执行失败
  • XxlJobHelper.log(): 记录执行日志
String param = XxlJobHelper.getJobParam(); long jobId = XxlJobHelper.getJobId(); log.info("当前执行的任务ID: {}", jobId); XxlJobHelper.handleSuccess("任务执行成功"); XxlJobHelper.log("任务执行异常: {}", e.getMessage()); XxlJobHelper.handleFail("任务执行异常: " + e.getMessage());

单个参数

@XxlJob("TestOneHandler") public ReturnT<String> jobDemo(String s) throws Exception { String param = XxlJobHelper.getJobParam(); System.out.println("TestOneHandler执行参数:" + param); return SUCCESS; }

多个参数

在XXL-JOB调度中心的任务配置中,"任务参数"字段可以填写如下JSON格式内容:

{"startDate":"2026-07-01","endDate":"2026-07-31"}

解析方法

@Value("${config.record.intervalMinute:10}") private int batchMinutes; @XxlJob(value = "old2NewTransferJob") public void execute() { String jsonParam = XxlJobHelper.getJobParam(); try { if (!StringUtils.hasLength(jsonParam)) { String msg = "调度参数为空,请传入 JSON: {\"startDate\":\"2024-01-01\",\"endDate\":\"2024-01-31\"}"; log.error(msg); XxlJobHelper.handleFail(msg); return; } JSONObject json = JSON.parseObject(jsonParam); String startDate = json.getString("startDate"); String endDate = json.getString("endDate"); if (!StringUtils.hasLength(startDate) || !StringUtils.hasLength(endDate)) { String msg = "调度参数缺少 startDate 或 endDate"; log.error(msg); XxlJobHelper.handleFail(msg); return; } String sourceTable = json.getString("sourceTable"); if (!StringUtils.hasLength(sourceTable)) { sourceTable = "call_log_old"; } log.info("开始迁移数据,源表:{}, 日期范围:{} ~ {}", sourceTable, startDate, endDate); long tt = System.currentTimeMillis(); long totalCount = 0; int batchCount = 0; String currentDate = startDate; while (currentDate.compareTo(endDate) <= 0) { // 每天按 batchMinutes 分钟分批处理1440=60*24分钟 for (int minute = 0; minute < 1440; minute += batchMinutes) { String timeStart = DateUtils.addMinute(currentDate, minute); String timeEnd = DateUtils.addMinute(currentDate, minute + batchMinutes); try { int count = callLogMapper.transferByTimeRange(sourceTable, timeStart, timeEnd); if (count > 0) { totalCount += count; batchCount++; log.info("迁移批次 {} ~ {} : {} 条", timeStart, timeEnd, count); } } catch (Exception e) { log.error("迁移失败 {}/{}, 时间范围:{} ~ {}", sourceTable, currentDate, timeStart, timeEnd, e); } } currentDate = DateUtils.addDay(currentDate, 1); } long elapsed = System.currentTimeMillis() - tt; String msg = String.format("迁移完成,源表:%s, 日期:%s~%s, 总批次数:%d, 总记录数:%d, 耗时:%dms", sourceTable, startDate, endDate, batchCount, totalCount, elapsed); log.info(msg); XxlJobHelper.handleSuccess(msg); } catch (Exception e) { String msg = String.format("迁移作业失败,param:%s,throw:%s", jsonParam, e.getMessage()); log.error("迁移作业失败", e); XxlJobHelper.handleFail(msg); } }

任务策略

路由策略

当您在 XXL-JOB 调度中心创建或编辑任务时,可以设置以下路由策略:

  • FIRST(第一个):固定选择注册到执行器的第一个节点执行
  • LAST(最后一个):固定选择注册到执行器的最后一个节点执行
  • ROUND(轮询):按照顺序轮询选择执行节点
  • RANDOM(随机):随机选择执行节点
  • CONSISTENT_HASH(一致性HASH):根据任务参数进行一致性HASH选择
  • LEAST_FREQUENTLY_USED(最不经常使用):选择历史执行次数最少的节点
  • LEAST_RECENTLY_USED(最近最久未使用):选择最近最久未执行的节点
  • FAILOVER(故障转移):失败转移,如果某个节点失败则转移到下一个节点
  • BUSYOVER(忙碌转移):如果某个节点忙碌则转移到空闲节点
  • SHARDING_BROADCAST(分片广播):向所有注册节点广播执行任务

路由策略使用场景

1. FIRST(第一个)

使用场景:

  • 主备模式:指定主节点处理关键任务
  • 固定执行节点:某些任务需要在特定环境下运行
  • 测试环境:指定测试节点执行任务

典型应用:

  • 核心数据同步任务
  • 系统状态检查任务
  • 主节点数据汇总任务

2. LAST(最后一个)

使用场景:

  • 备用节点执行:作为备用方案执行任务
  • 新节点优先:新加入的节点优先执行任务

典型应用:

  • 灰度发布环境下的任务执行
  • 新版本执行器测试任务

3. ROUND(轮询)

使用场景:

  • 负载均衡:多个执行器平均分配任务
  • 无状态任务分发
  • 避免单点过载

典型应用:

  • 定时数据清理任务
  • 日志分析任务
  • 批量数据处理任务

4. RANDOM(随机)

使用场景:

  • 简单负载均衡
  • 容错性要求高但无严格顺序要求的任务
  • 分散执行压力

典型应用:

  • 数据采样任务
  • 健康检查任务
  • 缓存预热任务

5. CONSISTENT_HASH(一致性HASH)

使用场景:

  • 根据任务参数固定分配执行节点
  • 分布式缓存场景
  • 需要最小化节点变更影响的场景

典型应用:

  • 用户数据处理任务(按用户ID分片)
  • 订单处理任务(按订单ID分片)
  • 内容分发任务

6. LEAST_FREQUENTLY_USED(最不经常使用)

使用场景:

  • 平衡各节点执行次数
  • 避免某些节点过载
  • 长期运行的任务调度优化

典型应用:

  • 长周期统计任务
  • 资源监控任务
  • 性能分析任务

7. LEAST_RECENTLY_USED(最近最久未使用)

使用场景:

  • 平衡各节点执行频率
  • 避免热点节点
  • 公平调度需求

典型应用:

  • 定期维护任务
  • 系统优化任务
  • 资源回收任务

8. FAILOVER(故障转移)

使用场景:

  • 高可用要求场景
  • 关键业务任务执行
  • 不能容忍任务失败的场景

典型应用:

  • 核心数据备份任务
  • 业务告警任务
  • 交易确认任务

9. BUSYOVER(忙碌转移)

使用场景:

  • 动态负载均衡
  • 实时性要求较高的任务
  • 避免任务在忙碌节点堆积

典型应用:

  • 实时数据处理任务
  • 紧急告警任务
  • 在线数据分析任务

10. SHARDING_BROADCAST(分片广播)

@Component @Slf4j public class ShardingExampleTask { @XxlJob("shardingExampleJob") public void shardingExample() { // 获取分片参数 int shardIndex = XxlJobHelper.getShardIndex(); int shardTotal = XxlJobHelper.getShardTotal(); log.info("开始执行分片任务,当前分片序号: {},总分片数: {}", shardIndex, shardTotal); // 根据分片参数处理不同数据 processShardingData(shardIndex, shardTotal); log.info("分片任务执行完成"); } private void processShardingData(int shardIndex, int shardTotal) { // 示例:处理用户数据,按用户ID分片 List<User> allUsers = userService.getAllUsers(); for (int i = 0; i < allUsers.size(); i++) { // 分片逻辑:index % total == shardIndex if (i % shardTotal == shardIndex) { User user = allUsers.get(i); processUser(user); } } } private void processUser(User user) { // 处理单个用户逻辑 log.info("处理用户: {}", user.getId()); } }

使用场景:

  • 大数据量分片处理
  • 并行处理需求
  • 需要所有节点同时执行任务

典型应用:

  • 大规模数据清洗任务
  • 全量数据统计任务
  • 分布式计算任务
  • 系统批量更新任务

阻塞处理策略

XXL-JOB提供了多种阻塞处理策略,用于控制当任务执行时间超过调度周期时的行为,确保任务调度的稳定性和可靠性。

阻塞处理策略类型

在XXL-JOB调度中心的任务配置中,"阻塞处理策略"字段有以下几种选择:

  • 单机串行:默认策略,同一任务在同一个执行器上只能有一个实例在运行
  • 丢弃后续调度:如果前一个任务未完成,后续调度将被丢弃
  • 覆盖之前调度:新调度会覆盖之前的任务执行
  • 允许并发:允许多个任务实例同时执行

不同策略的适用场景

  • 单机串行:适用于需要保证任务顺序执行的场景,如数据同步、报表生成等
  • 丢弃后续调度:适用于对实时性要求不高的任务,避免资源浪费
  • 覆盖之前调度:适用于需要最新数据的任务,如缓存更新、状态刷新等
  • 允许并发:适用于可以并行处理的任务,如批量数据处理、文件下载等

调度过期策略

XXL-JOB的调度过期策略是指当任务执行时间超过调度周期时,系统如何处理后续调度请求的策略。这直接影响到任务的执行频率和可靠性。

调度过期策略类型

在XXL-JOB调度中心的任务配置中,"调度过期策略"字段有以下几种选择:

  • 立即执行:无论前一个任务是否完成,都立即执行新的调度
  • 等待执行:等待前一个任务完成后才开始新的调度
  • 丢弃执行:如果前一个任务未完成,直接丢弃新的调度请求
  • 覆盖执行:新调度会覆盖之前的任务执行

不同策略的适用场景

  • 立即执行:适用于对实时性要求极高的任务,如监控告警、实时数据同步等
  • 等待执行:适用于需要保证任务完整性的场景,如报表生成、数据备份等
  • 丢弃执行:适用于对实时性要求不高的任务,避免资源浪费
  • 覆盖执行:适用于需要最新数据的任务,如缓存更新、状态刷新等
http://www.jsqmd.com/news/1334969/

相关文章:

  • 2026石家庄名包回收须知 小何收的顶规范二手奢品交易渠道 - 小何收的顶
  • 51单片机热水器饮水机液位防干烧温度控恒温水箱140-21(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_
  • 台州软考高级培训 - 众智商学院职业教育
  • 2026年8月联想晋江授权售后信息清单与送修附件清单与信息核验 - 数码品牌推荐
  • 终极指南:Vessel框架核心组件详解——从Cargo到Driver
  • 2026AI搜索效果验证工具哪家好?避坑指引及优选推荐
  • QSS样式表编辑器:提升Qt开发效率的终极工具
  • 企业级Taro React组件库架构深度解析:Taroify如何重构多端开发体验
  • YimMenu终极指南:免费GTA5安全增强与功能扩展完整教程
  • NBTExplorer:零基础掌握Minecraft数据编辑的终极指南
  • 从零到生产:FastAPI + LangGraph 智能体生产级模板深度解析
  • 从基础到高级:Let‘s Build a Shell! 项目扩展功能全解析
  • 3步实现Android按键自定义:用KeyMapper打造你的专属快捷键系统
  • Cement-a: An Ontology-based Data Access System for Building Analytics with Multiple Data Sources
  • 儿童证件照可以自己拍吗?线上快速制作方法 - 跑政通
  • 云南全封闭武术学校:2026年叛逆期孩子适合去吗?教育效果真实反馈 - 圣龙武术朱老师
  • 2026年8月豆包算法更新后,什么样的豆包关键词优化公司才跟得上节奏 - 品牌深度评测
  • PySide6 QDateTimeEdit控件:5个实用技巧让日期时间选择更高效
  • 为什么你的Modbus调试总是效率低下?这款免费开源工具能彻底改变你的工作方式
  • 【AI】DeepSeek-V4-Flash-0731:更便宜的模型,反超自家旗舰
  • 解锁reMarkable无限潜能:300+开源工具打造极致电子纸体验
  • RimSort:如何让环世界上百个模组和谐共处?开源MOD管理器的智能解决方案
  • 生产级AI智能体的可观测性实战:从指标监控到LLM评估
  • AI时代,小白程序员如何拥抱大模型浪潮?收藏这份成长指南!
  • 2026年8月联想福州授权售后信息清单与取机验收与维修后复测 - 品牌售后
  • 2026年8月戴尔泉州售后授权服务核验要点及屏幕显示异常与售后检测 - 数码产品售后
  • 2026年辽宁武术学校:正规办学资质+奥运冠军技术指导 - 圣龙武术朱老师
  • 2026跨省托运电动车指南:哪个平台靠谱?费用揭秘+避坑攻略 - 快递物流资讯
  • DeepCreamPy终极指南:3步掌握AI图像修复黑科技
  • 音乐解锁工具完整指南:轻松解除网易云音乐和QQ音乐加密限制