XXL-JOB简单入门
xxl-job-core 2.4.0
springboot 2.7.16
XXL-JOB是什么?
XXL-JOB是一个分布式的任务调度框架,通过引入XXL-JOB相关的依赖,按照相关格式撰写代码后,可在其可视化界面进行任务的启动,执行,中止以及包含了日志记录与查询和任务状态监控
为什么学习XXL-JOB?
一、单机定时任务容易在集群环境下被重复执行
微服务A具备定时任务调度(例如Quartz)的功能。
然而,由于微服务A的流量已经超出了其承受范围,我们决定采用分布式集群的方式来部署多个微服务A。这样一来,定时任务调度将会被多次执行。
二、XXL-JOB提供了前端页面更好的管理
运维界面:XXL-JOB提供了方便的运维界面,可以直观的管理作业和注册中心。
三、XXL-JOB支持集群有利于提高系统负载能力和高可用性
支持集群部署:XXL-JOB支持集群部署,有利于提高系统负载能力和高可用性。
四、XXL-JOB支持邮箱报警和日志记录
如执行失败查看日志、邮件报警、路由策略(包括轮询等)、快速识别执行器问题或新增等。
XXL-JOB的使用场景
- 定时任务:XXL-JOB可以用来执行定时任务,例如每天凌晨进行数据备份、每小时进行数据同步等。
- 异步任务:XXL-JOB可以用来执行异步任务,例如用户下单后异步发送邮件或短信通知。
- 流量削峰:XXL-JOB可以用来执行流量削峰任务,例如在高峰期将部分任务延迟执行。
- 分布式任务:XXL-JOB可以用来执行分布式任务,例如大数据处理、分布式爬虫等。
- 复杂调度:XXL-JOB支持CRON表达式,因此可以满足复杂的调度需求。
- 微服务解耦:在微服务架构中,XXL-JOB可以用来解耦服务,提高系统的稳定性和可用性。
XXL-JOB是如何工作的?
通常只有:
- 调用中心
- 执行器
这两个部分
调度中心可以下载XXL-JOB项目中的xxl-job-admin项目,并修改配置文件以启动。
执行器是连接到调度中心的节点,它负责接收和执行任务。执行器自带了一些任务,这些任务需要在执行器(微服务节点)中编写业务代码,并为它们命名。. 比如:
上面的demoJobHandler就是名字, 函数体内可以写定时任务
那么什么时候执行我们的代码呢?
简单, 需要去web上配置
XXL-JOB WEB端配置详解
基础配置:
- 执行器:任务的绑定的执行器,任务触发调度时将会自动发现注册成功的执行器, 实现任务自动发现功能; 另一方面也可以方便的进行任务分组。每个任务必须绑定一个执行器, 可在 "执行器管理" 进行设置;
- 任务描述:任务的描述信息,便于任务管理;
- 负责人:任务的负责人;
- 报警邮件:任务调度失败时邮件通知的邮箱地址,支持配置多邮箱地址,配置多个邮箱地址时用逗号分隔;
触发配置:
-
调度类型:
- 无:该类型不会主动触发调度;
- CRON:该类型将会通过CRON,触发任务调度;
- 固定速度:该类型将会以固定速度,触发任务调度;按照固定的间隔时间,周期性触发;
- 固定延迟:该类型将会以固定延迟,触发任务调度;按照固定的延迟时间,从上次调度结束后开始计算
- 延迟时间,到达延迟时间后触发下次调度;
-
CRON:触发任务执行的Cron表达式;
-
固定速度:固定速度的时间间隔,单位为秒;
-
固定延迟:固定延迟的时间间隔,单位为秒;
任务配置:
-
运行模式:
- BEAN模式:任务以JobHandler方式维护在执行器端;需要结合 "JobHandler" 属性匹配执行器中任务;
- GLUE模式(Java):任务以源码方式维护在调度中心;该模式的任务实际上是一段继承自IJobHandler的Java类代码并 "groovy" 源码方式维护,它在执行器项目中运行,可使用@Resource/@Autowire注入执行器里中的其他服务;
- GLUE模式(Shell):任务以源码方式维护在调度中心;该模式的任务实际上是一段 "shell" 脚本;
- GLUE模式(Python):任务以源码方式维护在调度中心;该模式的任务实际上是一段 "python" 脚本;
- GLUE模式(PHP):任务以源码方式维护在调度中心;该模式的任务实际上是一段 "php" 脚本;
- GLUE模式(NodeJS):任务以源码方式维护在调度中心;该模式的任务实际上是一段 "nodejs" 脚本;
- GLUE模式(PowerShell):任务以源码方式维护在调度中心;该模式的任务实际上是一段 "PowerShell" 脚本;
-
JobHandler:运行模式为 "BEAN模式" 时生效,对应执行器中新开发的JobHandler类“@JobHandler”注解自定义的value值;
-
执行参数:任务执行所需的参数;
高级配置:
-
路由策略:当执行器集群部署时,提供丰富的路由策略,包括;
- FIRST(第一个):固定选择第一个机器;
- LAST(最后一个):固定选择最后一个机器;
- ROUND(轮询):;
- RANDOM(随机):随机选择在线的机器;
- CONSISTENT_HASH(一致性HASH):每个任务按照Hash算法固定选择某一台机器,且所有任务均匀散列在不同机器上。
- LEAST_FREQUENTLY_USED(最不经常使用):使用频率最低的机器优先被选举;
- LEAST_RECENTLY_USED(最近最久未使用):最久未使用的机器优先被选举;
- FAILOVER(故障转移):按照顺序依次进行心跳检测,第一个心跳检测成功的机器选定为目标执行器并发起调度;
- BUSYOVER(忙碌转移):按照顺序依次进行空闲检测,第一个空闲检测成功的机器选定为目标执行器并发起调度;
- SHARDING_BROADCAST(分片广播):广播触发对应集群中所有机器执行一次任务,同时系统自动传递分片参数;可根据分片参数开发分片任务;
-
子任务:每个任务都拥有一个唯一的任务ID(任务ID可以从任务列表获取),当本任务执行结束并且执行成功时,将会触发子任务ID所对应的任务的一次主动调度。
-
调度过期策略:
- 忽略:调度过期后,忽略过期的任务,从当前时间开始重新计算下次触发时间;
- 立即执行一次:调度过期后,立即执行一次,并从当前时间开始重新计算下次触发时间;
-
阻塞处理策略:调度过于密集执行器来不及处理时的处理策略;
-
单机串行(默认):调度请求进入单机执行器后,调度请求进入FIFO队列并以串行方式运行;
-
丢弃后续调度:调度请求进入单机执行器后,发现执行器存在运行的调度任务,本次请求将会被丢弃并
标记为失败;
-
覆盖之前调度:调度请求进入单机执行器后,发现执行器存在运行的调度任务,将会终止运行中的调度任务并清空队列,然后运行本地调度任务;
-
-
任务超时时间:支持自定义任务超时时间,任务运行超时将会主动中断任务;
-
失败重试次数;支持自定义任务失败重试次数,当任务失败时将会按照预设的失败重试次数主动进行重试;
XXL-JOB怎么用?
使用XXL-JOB主要分为两步配置即可完成一个简单的任务调度中心,
- 第一步,配置调度中心
- 第二步,配置执行器
配置调度中心项目
直接下载就好了
| 源码仓库地址 | Release Download |
|---|---|
| github.com/xuxueli/xxl… | Download |
| gitee.com/xuxueli0323… | Download |
直接将上面的调度中心项目打包执行完事
当然你也可以使用docker运行调度中心, 具体: 记一次 xxl-job 实战
其中application.properties中的几个配置需要注意下
调度中心端口
server.port=8081
调度中心数据库
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
下面我们会导入表结构的
报警邮箱地址
spring.mail.host=smtp.qq.com spring.mail.port=25 spring.mail.username=xxx@qq.com spring.mail.from=xxx@qq.com spring.mail.password=xxx spring.mail.properties.mail.smtp.auth=true spring.mail.properties.mail.smtp.starttls.enable=true spring.mail.properties.mail.smtp.starttls.required=true spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
连接access_token
xxl.job.accessToken=default_token
调度中心需要和执行器相同的验证方式
对了可能还需要在启动类上加上
@MapperScan(basePackages = "com.xxl.job.admin.dao")
表结构导入
主要看在上面的路径下
调度中心访问地址: http://localhost:8080/xxl-job-admin
默认登录账号 “admin/123456”, 登录后运行界面如下图所示。
配置部署执行器项目
导入maven包
application配置
添加执行器配置
添加任务处理类
添加任务类型和触发时机
GLUE模式
在线编写代码, 在执行器中执行代码的功能
分片广播
是什么?
一个任务广播给所有节点执行
为什么?
假设我们有一个任务,即向10000个客户发送邮件。如果采用轮询策略,这个任务只能由一个节点执行。然而,如果我们选择分片广播的策略,我们可以将这个大任务拆分成10000个子任务,然后依次分配给几个节点进行处理。
"如果采用轮询策略,这个任务只能由一个节点执行"
注意上面这句话的意思, 是一个任务丢给执行器执行, 而任务中有无数个数据需要处理, 明显这无数个数据交给一个执行器肯定不合理, 所以需要分片广播方式
怎么做?
输入: 一个任务所需的多个数据项。
处理器: 通过使用多个待处理数据项的ID,对执行器总数进行取模运算,得到的结果与当前正在执行的执行器的序号进行比较。如果两者相等,则该数据项将被获取并交给当前执行器进行处理。
输出: 所有数据项处理完毕后,状态为1表示处理完成。
XXL-JOB提供了两个函数:
有了这两个属性,当执行器扫描数据库获取记录时,可以根据 取模 的方式获取属于当前执行器的任务,可以这样编写 sql 获取任务记录:
表结构:
CREATE TABLE t_user_mobile_plan ( id bigint NOT NULL AUTO_INCREMENT, username varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, nickname varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, phone varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, info varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, status int NOT NULL DEFAULT '0' COMMENT '0 任务未开始, 1 任务处理中 2 任务完成 3 处理失败', PRIMARY KEY (id) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=2001 DEFAULT CHARSET=utf8mb3 ROW_FORMAT=DYNAMIC;
数据随便插入点就行了
数据被重复处理的问题
上面的状态 0 任务未开始, 1 任务处理中 2 任务完成 3 处理失败, 这个状态可以避免数据被重复消费
如下如所示, 执行器3 失败之后, 第四个五角星被重复消费
请查看上图虚线部分,原本第四个五角星应该由执行器1来处理。然而,由于执行器3的消失,执行器总数变为2,因此现在执行器2准备挑选五角星。在这种情况下,第四个五角星再次被分配给了执行器2。
如果我们引入状态的概念,当任务被交给执行器1处理后,五角星的状态会被修改为“正在处理中”。在这种情况下,执行器2将无法获取第四个五角星。