xxl-job分布式定时任务
官方定义:
xxl-job 是一个开源的分布式任务调度平台。它的核心设计目标是开发迅速、学习简单、轻量级、易扩展。主要由调度中心和执行器两部分组成,调度中心负责管理调度信息,执行器负责接收调度请求并执行任务逻辑。
主要特点:
-
简单易用:支持通过 web 页面对任务进行增删改查等操作,操作简单,易于上手。
-
动态性:支持动态修改任务状态、启动 / 停止任务,以及终止运行中的任务,并且都是即时生效的。
-
调度中心高可用:调度采用中心式设计,自研调度组件并支持集群部署,可保证调度中心的高可用性。
-
执行器高可用:任务分布式执行,任务 “执行器” 支持集群部署,可保证任务执行的高可用性。
-
多种任务类型支持:支持多种任务执行器,如 shell 任务、Java 任务、Spring 任务等,可以满足不同场景下的任务执行需求。
-
调度过期策略:具备调度错过调度时间的补偿处理策略,包括忽略、立即补偿触发一次等。
-
阻塞处理策略:当调度过于密集执行器来不及处理时,提供单机串行(默认)、丢弃后续调度、覆盖之前的调用等处理策略。
-
任务超时控制:支持自定义任务超时时间,任务运行超时将会主动中断任务。
-
失败重试与告警:提供任务执行失败重试的机制,以确保任务的可靠性,同时支持通过邮件、短信等方式通知用户任务的执行结果和异常情况。
-
监控和日志管理:提供任务执行的监控和日志管理功能,用户可以实时查看任务的执行状态和日志输出,有助于快速定位和解决任务执行过程中的问题。
主要原理:
xxl-job 的主要原理是将任务的调度与执行进行解耦。调度中心作为独立的项目,负责发现执行器、触发定时任务,以及任务管理、执行器管理、日志管理等。执行器与业务项目整合,接收调度中心的执行请求、终止请求和日志请求等。调度中心和执行器之间通过 HTTP 协议进行通信。在任务执行过程中,调度中心根据配置的时间规则等信息触发任务,将任务信息发送给执行器,执行器接收到任务后执行具体的任务逻辑,并将执行结果返回给调度中心进行记录和监控。
主要流程:
-
环境搭建:
-
拉取源码:从官方仓库拉取 xxl-job 的源码到本地。
-
初始化数据库:在项目的
doc/db
路径下找到数据库脚本文件(如tables_xxl_job.sql
),在 MySQL 等数据库中运行该脚本,初始化数据库表结构。 -
配置文件修改:修改调度中心和执行器的配置文件,如调度中心的数据库连接信息、报警邮箱、访问令牌、线程池配置等,以及执行器的调度中心地址、执行器名称、端口等信息。
-
-
调度中心启动:启动调度中心项目,调度中心会自动初始化相关的组件,如任务管理器、注册表监视器、触发池等。
-
执行器注册:在业务项目中引入 xxl-job 的执行器依赖,并配置好执行器相关信息后,执行器所在项目启动时会随之启动一个服务器,并自动向调度中心注册。
-
任务配置:通过调度中心的 web 界面创建任务,配置任务的执行时间、执行器、任务参数、路由策略等信息。
-
任务调度与执行:调度中心根据任务的配置信息,按照时间规则触发任务,将任务信息发送给相应的执行器,执行器执行任务并返回结果,调度中心记录任务的执行日志和状态。
主要应用场景:
-
时间驱动场景:如定时发送优惠券、发送营销短信、发送房贷短信等,在特定的时间点或时间间隔执行相关的业务操作。
-
批量数据处理场景:批量统计数据,如统计上个月的账单、销售数据等,可按照设定的时间周期自动执行数据统计任务。
-
数据同步场景:在不同的系统或数据库之间进行数据同步,定期将数据从一个数据源同步到另一个数据源。
-
系统监控与维护场景:定期执行系统监控任务,如检查系统的运行状态、清理缓存、备份数据等,以保证系统的稳定运行。
与主流技术的相似点和区别:
-
与 Quartz 的相似点和区别:
-
相似点:Quartz 是一款开源的定时任务框架,xxl-job 在一定程度上借鉴了 Quartz 的设计理念,两者都有任务、触发器等核心概念,并且都通过数据库锁来控制任务不能重复执行。
-
区别:xxl-job 是分布式的任务调度平台,弥补了 Quartz 不支持并行调度、不支持失败处理策略和动态分片的策略等诸多不足。同时,xxl-job 有管理界面,上手比较容易,适用于分布式场景下的使用,而 Quartz 更侧重于单机或简单的定时任务场景。
-
-
与 Elastic-Job 的相似点和区别:
-
相似点:Elastic-Job 和 xxl-job 都是分布式任务调度框架,都致力于解决分布式环境下的任务调度问题,都具备高可用、任务分片等功能。
-
区别:Elastic-Job 是当当网开发的,采用 Zookeeper 实现分布式协调,实现任务高可用以及分片,功能丰富强大,但使用和运维有一定的复杂性。xxl-job 环境依赖于 MySQL,通过一个中心式的调度平台调度多个执行器执行任务,调度中心通过数据库锁保证集群分布式调度的一致性,相对来说更轻量级,开箱即用,操作简易,上手快,与 Spring Boot 有非常好的集成。
-
快速入门
xxl-job管理平台:
XXL-JOB 是一个轻量级的分布式任务调度框架,适用于 Java 项目。以下是一个快速入门指南,帮助你在项目中实现 XXL-JOB。
1. 环境准备
确保你的环境中已经安装了以下软件:
-
JDK 1.8 及以上
-
Maven
-
MySQL(用于存储调度信息)
2. 引入依赖
在你的项目中添加 XXL-JOB 的 Maven 依赖。在 pom.xml
中添加:
xmlCopy Code<dependency> <groupId>com.xxl.job</groupId> <artifactId>xxl-job-core</artifactId> <version>2.3.0</version> <!-- 请根据最新版本调整 --> </dependency>
3. 配置数据库
在 MySQL 中创建一个数据库,例如 xxl_job
,并执行 XXL-JOB 的 SQL 脚本 来初始化调度表。
4. 配置 XXL-JOB Admin
下载并启动 XXL-JOB Admin:
-
从 XXL-JOB GitHub 下载
xxl-job-admin
,并运行XXL-JOB-ADMIN
模块。
在 application.properties
中配置数据库连接:
propertiesCopy Codespring.datasource.url=jdbc:mysql://localhost:3306/xxl_job spring.datasource.username=your_username spring.datasource.password=your_password spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
5. 创建任务执行器
创建一个 Java 类,实现任务逻辑:
javaCopy Codeimport com.xxl.job.core.handler.annotation.XxlJob; import org.springframework.stereotype.Component; @Component public class MyJobHandler { @XxlJob("myJobHandler") // 任务名称 public void execute() throws Exception { System.out.println("执行定时任务"); // 任务逻辑 } }
6. 配置 Spring Boot
在 application.properties
中添加 XXL-JOB 配置:
propertiesCopy Codexxl.job.admin.addresses=http://localhost:8080/xxl-job-admin xxl.job.executor.appname=your_app_name xxl.job.executor.address= xxl.job.executor.ip=127.0.0.1 xxl.job.executor.port=9999 xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler xxl.job.executor.logretentiondays=30
7. 启动执行器
在你的 Spring Boot 应用中启动 XXL-JOB 执行器。添加启动类:
javaCopy Codeimport org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class JobApplication { public static void main(String[] args) { SpringApplication.run(JobApplication.class, args); } }
8. 在 XXL-JOB Admin 中配置任务
-
访问
http://localhost:8080/xxl-job-admin
。 -
使用默认用户名和密码(admin/admin)登录。
-
在“任务管理”中添加新任务,指定
myJobHandler
为 Handler 名称。
9. 测试任务
你可以手动触发任务,查看日志和输出,以确认任务是否正常执行。
xxl-job路由策略,运行模式,阻塞处理策略,JobHandler
在 XXL-JOB 中,路由策略、运行模式、阻塞处理策略和 JobHandler 是核心概念。下面逐一介绍这些内容:
1. 路由策略
路由策略用于决定任务调度时如何选择执行器。主要有以下几种策略:
1. 轮询 (BEAT)
解释: 任务按顺序分配给所有在线的执行器,确保每个执行器都能得到相同数量的任务。
示例: 假设有三个执行器 A、B、C。第一次调度任务分配给 A,第二次给 B,第三次给 C,然后再次从 A 开始。
2. 第一个 (FIRST)
解释: 始终选择列表中的第一个执行器来执行任务。
示例: 如果有执行器 A、B、C,所有任务都将被分配给 A,不论 A 是否忙碌。
3. 最后一个 (LAST)
解释: 始终选择列表中的最后一个执行器来执行任务。
示例: 类似于第一个策略,如果有执行器 A、B、C,所有任务都会分配给 C。
4. 随机 (RANDOM)
解释: 从在线的执行器中随机选择一个执行器来处理任务。
示例: 有执行器 A、B、C,任务可能被分配给任意一个执行器,如 A、B 或 C。
5. 一致性HASH (CONSISTENT_HASH)
解释: 通过哈希算法将任务分配给特定的执行器,确保同样的任务在后续调度中会分配给同一个执行器。
示例: 如果有一个特定的任务 ID,根据哈希计算的结果总是将该任务分配给执行器 A。
6. 最不经常使用 (LEAST_LOADED)
解释: 将任务分配给当前负载最低的执行器。
示例: 如果执行器 A 处理 5 个任务,B 处理 2 个,C 处理 3 个,新的任务会被分配给 B。
7. 最近最久未使用 (LRU)
解释: 将任务分配给最近未被使用的执行器。
示例: 如果执行器 A 最近被使用过,B 和 C 未被使用,那么新的任务会分配给 B 或 C。
8. 故障转移 (FAILOVER)
解释: 当一个任务执行失败时,会选择其他的执行器来重试该任务。
示例: 如果任务在执行器 A 上失败,系统会自动将任务转移到 B 或 C 执行。
9. 忙碌转移 (BUSY)
解释: 当执行器忙碌时,任务会转移到其他空闲的执行器。
示例: 如果执行器 A 正在处理任务,新的任务会分配给 B 或 C。
10. 分片广播 (SHARDING_BROADCAST)
解释: 任务会被分配到所有在线的执行器上,并由每个执行器独立执行。
示例: 如果有执行器 A、B、C,每个执行器都会收到相同的任务,并独立执行,适合任务可以并行处理的场景。
2. 运行模式
运行模式: BEAN模式:任务以JobHandler方式维护在执行器端;
3. 阻塞处理策略
XXL-JOB 的阻塞处理策略主要用于处理任务的调度情况,以确保系统稳定性和有效性。
1. 单机串行
解释: 当某个任务正在执行时,后续的相同任务会在当前任务执行完成后再执行,即使多个调度请求到达,也会被串行处理。
示例: 假设有一个任务每天需要处理用户注册,如果这个任务每次执行需要 5 分钟,而系统每分钟都有新的请求到来,那么这些请求会被排队,直到上一个请求执行完成。即使有 10 个请求到达,系统也会依次处理,确保每个请求都完成。
2. 丢弃后续调度
解释: 当一个任务正在执行时,任何后续的调度请求会被丢弃,不再处理。
示例: 设想一个任务负责处理大数据分析,每次执行可能需要 30 分钟。如果在执行期间又有新的调度请求到来,这些请求会被丢弃。这样,系统只会执行第一个请求,后面的请求不会进入队列,有助于防止系统过载。
3. 覆盖之前调度
解释: 当任务正在执行时,后续的调度请求会替代之前的调度,即只有最后一个请求会被执行,之前的所有请求会被覆盖。
示例: 假设有一个任务用于更新数据库中的价格信息。如果这个任务每隔 10 分钟被调度执行,而在任务执行过程中又收到新的更新请求,这时最后一次请求会覆盖之前的请求。最终,系统只会执行最后一次更新,确保数据库中的价格信息是最新的。
4. JobHandler
JobHandler 是实现任务逻辑的类,负责定义具体的任务执行逻辑。
需要结合 “JobHandler” 属性匹配执行器中任务;
JobHandler:运行模式为 “BEAN模式” 时生效,对应执行器中新开发的JobHandler类“@JobHandler”注解自定义的value值;
一个 JobHandler 通常包含以下几个部分:
-
@XxlJob 注解: 用于标识任务的名称和类型。
-
执行方法: 定义任务的具体实现。
示例代码:
javaCopy Codeimport com.xxl.job.core.handler.annotation.XxlJob; import org.springframework.stereotype.Component; @Component public class MyJobHandler { @XxlJob("myJobHandler") // 任务名称 public void execute() throws Exception { // 任务逻辑 System.out.println("执行定时任务"); } }
总结
这些核心概念结合在一起,使得 XXL-JOB 成为一个灵活且强大的分布式任务调度框架。通过合理配置路由策略、运行模式和阻塞处理策略,可以有效地管理和调度任务。如果有其他具体问题,欢迎继续提问!