前言
任务调度场景
概述
| 1. 在平时的业务场景中,经常有一些场景需要使用定时任务 |
时间驱动的场景
| 1. 某个时间点发送优惠券,发送短信等等 |
| 2. 报表 |
| 3. 爬虫 |
批量处理数据
| 1. 批量统计上个月的账单,统计上个月销售数据等等 |
固定频率的场景
为什么需要任务调度平台
在Java中,传统的定时任务实现方案,比如Timer,Quartz等
缺点
| 不支持集群、不支持统计、没有管理平台、没有失败报警、没有监控等等 |
分布式的架构中,有一些场景需要分布式任务调度
| 1. 同一个服务多个实例的任务存在互斥时,需要统一的调度 |
| 2. 任务调度需要支持高可用、监控、故障告警 |
| 3. 需要统一管理和追踪各个服务节点任务调度的结果,需要记录保存任务属性信息等 |
任务调度框架
| 1. 非分布式 |
| 在单一个服务器当中,创建定时任务 |
| @Scheduled |
| 2. 分布式 |
| 把分散的,可靠性差的计划任务纳入统一的平台,并实现集群管理调度和分布式部署的一种定时任务的管理方式,叫做分布式定时任务。 |
| 2.1 Quartz |
| 先驱者 |
| 无图形化界面 |
| 接口不人性化 |
| 2.2 Elasticjob |
| 基于Quartz |
| elastic-job 是由当当网基于quartz 二次开发之后的分布式调度解决方案 |
| 依赖很多中间件 zk, |
| 2.3 xxl-job |
| 美团点评里面开发者开发出来 |
| 2.4 SchedulerX |
| 阿里云出的一个框架 |
| 商用产品 |
| 2.5 PowerJob |
| 个人 |
| 2.6 对比 |

XXL-job
| 1. 本次使用的是2.3.0版本的 |
| 2. 我感觉有bug 启动多个服务xxl-job始终有一个服务是超时的 |
官网
| 1. https://www.xuxueli.com/xxl-job/ |
| 2. https://gitee.com/xuxueli0323/xxl-job/ |
概述
| 1. xxl-job是出自大众点评许雪里(xxl就是作者名字的拼音首字母)的开源项目,官网上介绍这是一个轻量级分布式任务调度框架, |
| |
| 2. 其核心设计目标是开发迅速、学习简单、轻量级、易扩展。跟elasticjob不同,xxl-job环境依赖于mysql,不用ZooKeeper,这也是最大的不同。 |
| |
| 3. xxl-job中心式的调度平台轻量级,开箱即用,操作简易,上手快,与SpringBoot有非常好的集成,而且监控界面就集成在调度中心,界面又简洁, |
| |
| 4. 对于企业维护起来成本不高,还有失败的邮件告警等等。这就使很多企业选择xxl-job做调度平台。 |
系统组成
| 1. 调度模块(调度中心) |
| 1.1 负责管理调度信息,按照调度配置发出调度请求,自身不承担业务代码。 |
| |
| 1.2 调度系统与任务解耦,提高了系统可用性和稳定性,同时调度系统性能不再受限于任务模块; |
| |
| 1.3 支持可视化、简单且动态的管理调度信息,包括任务新建,更新,删除,任务报警等,所有上述操作都会实时生效,同时支持监控调度结果以及执行日志,支持执行器Failover |
| |
| 2. 执行模块(执行器) |
| 1. 负责接收调度请求并执行任务逻辑。任务模块专注于任务的执行等操作,开发和维护更加简单和高效; 接收“调度中心”的执行请求、终止请求和日志请求等 |
| 3. 功能架构图 |

2个角色
调度任务管理系统,xll-job-admin
| 1. 设置时间 |
| 2. 集群,使用的策略 |
| 3. 创建任务时会指定任务名称,地址 |
xxl-job-excutor,通常是我们业务系统
| 1. 配置上调度系统的地址 |
| 2. 创建任务,在任务上指定任务名称 |
搭建调度中心
下载源码
| 1. https://github.com/xuxueli/xxl-job/releases/tag/2.3.0 |
执行SQL
| 1. /xxl-job-2.3.0/doc/db/tables_xxl_job.sql |
| 2. 将sql文件执行创建数据库 |
修改xxl-job-admin项目当中的appication.properties配置

切换到xxl-job-admin目录当中打包
| 1. mvn clean -U package -Dmaven.test.skip=true |
切换到target目录当中启动
| 1. java -jar xxl-job-admin-2.3.0.jar --server.port=8088 |
| |
| 2. http://localhost:8088/xxl-job-admin/toLogin |
| |
| 3. 用户名与密码 |
| admin |
| 123456 |
| 4. 主界面 |
| |


调度任务执行流程
| 1. 启动xll-job-admin调度模块,直接运行 |
| 2. xxl-job-excuotr需要配置xxl-job-admin的地址,主动向Xxl-job-admin注册 |
| 3. 流程图 |

执行器操作
创建springboot工程

导入依赖
| |
| <parent> |
| <groupId>org.springframework.boot</groupId> |
| <artifactId>spring-boot-starter-parent</artifactId> |
| <version>2.3.2.RELEASE</version> |
| </parent> |
| |
| <dependencies> |
| <dependency> |
| <groupId>org.springframework.boot</groupId> |
| <artifactId>spring-boot-starter-web</artifactId> |
| </dependency> |
| <dependency> |
| <groupId>org.projectlombok</groupId> |
| <artifactId>lombok</artifactId> |
| </dependency> |
| |
| <dependency> |
| <groupId>com.xuxueli</groupId> |
| <artifactId>xxl-job-core</artifactId> |
| <version>2.3.0</version> |
| </dependency> |
| </dependencies> |
添加配置文件

其他配置参考

配置
| server: |
| port: 8011 |
| xxl: |
| job: |
| admin: |
| addresses: http: |
| executor: |
| appname: yby-job-2 |
| logpath: /Users/yangbuyi/Documents/分布式任务调度/log |
创建配置类
| @Component |
| @Slf4j |
| public class XxlJobConfig { |
| @Value("${xxl.job.admin.addresses}") |
| private String adminAddresses; |
| @Value("${xxl.job.executor.appname}") |
| private String appname; |
| @Value("${xxl.job.executor.logpath}") |
| private String logPath; |
| @Bean |
| public XxlJobSpringExecutor xxlJobExecutor() { |
| XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor(); |
| xxlJobSpringExecutor.setAdminAddresses(adminAddresses); |
| xxlJobSpringExecutor.setAppname(appname); |
| xxlJobSpringExecutor.setLogPath(logPath); |
| return xxlJobSpringExecutor; |
| } |
| } |
在调度中心创建执行器与任务
在执行器管理当中创建执行器

| 1. 执行器的名称要和配置文件 当中的appname名称一样 |

切换到任务管理,创建任务

创建任务映射

启动项目-启动任务
注册到执行器当中


查看执行器我们可以看到执行当中有一个服务注册进来了

查看项目工程我们可以看到分布式任务开始执行了我们的程序

路径策略
| 1. 就是一个负载均衡 |
| 2. 当只有一个任务调度中心, 有多个执行器的时候 ,任务调度中心要选择一个或多个执行器来执行任务 |
对项目进行集群部署
| 1. 设置允许并行运行 |
| 2. 更改yml端口-进行运行 |

- 运行成功

- 可以看到注册了两台服务集群
- 我们可以看到10000是第一个那么到时候调度器就是按照这个顺序调用的

策略详解

一般使用故障转移
| 1. 修改任务管理调度器-故障转移 |
| 2. 当一台机器出现故障时, 转到移另一台机器上 |

启动多台服务注册到执行器

启动任务测试故障转移

执行之后我们可以发现
| 1. 按照我们注册到执行器的顺序来进行访问的 |
| 2. 我们进行将第一台服停止(宕机) |

宕机(10001)后我们可以看到 9999 接受到了呢?
| 2. 宕机(10001)后xxl-job会发送心跳检查是否能调用,请求不了后xxl-job将会继续按照顺序执行那么就轮到了9999 来进行调度任务的操作 |

示例图-日志--

分片策略
| 1. 获取当前服务的索引: XxlJobHelper.getShardIndex(); |
| 2. 获取执行器注册的总数: XxlJobHelper.getShardTotal(); |
| 3. 修改任务路由策略为- 分片广播 |
| 4. 启动3个服务(因为我发现启动多个服务始终有一个是请求超时所以我们要用2个则多启动一个即可,官方还没提示bug的处理方案.) |
| 5. 启动任务查看分片广播-分别发送了任务到两个服务上 |

| @XxlJob("myJobHandler") |
| public ReturnT<String> execute() { |
| |
| List<Integer> users = Arrays.asList(1, 2, 3, 4, 5, 6, 7); |
| for (Integer user : users) { |
| |
| |
| |
| if (user % XxlJobHelper.getShardTotal() == XxlJobHelper.getShardIndex()) { |
| log.info("给{}号学生发送短信:index={},total={}", user, XxlJobHelper.getShardIndex(), XxlJobHelper.getShardTotal()); |
| } |
| |
| } |
| |
| return ReturnT.SUCCESS; |
| } |
1-4-7 号任务分发到

其余的全部给到另外的服务上

我们就讲到着还有很多路由策略,一般使用的就是这两个.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南