XXL-JOB 入门教程之一

大纲

前言

什么是任务调度

任务调度就是我们常说的定时任务,定时任务是指在指定时间、指定的频率去执行任务(业务代码)。任务调度是日常开发中非常常见的一个业务场景,我们经常需要去运行一些的周期性、指定时间点等方式自动触发的异步业务逻辑。

集中式任务调度

集中式任务是与分布式任务恰好相反的概念,集中式任务就是单机任务,一个项目,一台机器,也就是我们常说的单体应用。对于集中式任务,也就是我们 Java 开发中常见的定时任务。

集中式任务调度的问题

如果采用集中式的任务调度方式,在分布式集群部署的模式下会带来一些问题,比如:

  • 多台机器集群部署的定时任务如何保证不被重复执行?
  • 如何动态地调整定时任务的执行时间(不重启服务的情况下)?
  • 部署定时任务的机器发生故障时,如何实现故障转移?
  • 如何对定时任务的执行情况进行监控?
  • 业务量较大,单机遭遇性能瓶颈问题,任务调度如何扩展?

集中式任务调度的缺点

  • 不支持分片任务:处理有序数据时,多机器分片执行任务处理不同数据。
  • 不支持生命周期统一管理:不重启服务的情况下关闭、启动任务。
  • 不支持集群:存在任务重复执行的问题。
  • 不支持失败重试:出现异常后任务终结,不能根据执行状态控制任务重新执行。
  • 不支持动态调整:在不重启服务的情况下,动态修改任务参数。
  • 不支持报警机制:在任务执行失败之后,没有报警机制。
  • 不支持任务数据统计:在任务数据量大时,对于任务执行情况无法高效地统计执行情况。

Java 实现集中式任务调度的方式

实现方式说明
while (true) + Thread.sleep轮询 + 线程休眠的方式实现定时任务(最古老的方法)
java.util.Timer + java.util.TimerTaskTimer 是一种定时器工具,用来在一个后台线程按计划执行指定任务,它可以按计划执行一个任务一次或反复多次。TimerTask 是一个抽象类,它的子类代表一个可以被 Timer 计划的任务。
ScheduledExecutorService从 JDK 1.5 开始,ScheduledExecutorService 做为并发工具类被引入,是最理想的定时任务实现方式
QuartzQuartz 是一个开源的定时任务调度框架,由 Java 编写而成,用于 Java 生态下的定时任务调度,是一个灵活方便、使用简单的定时任务调度框架,可以和 Spring 整合使用
Spring TaskSpring 框架从 3.0 版本开始提供的轻量级的定时任务调用工具,使用起来很方便
Spring Boot 注解 @EnableScheduling + @Scheduled底层依然是采用 Spring Task 来实现任务调度

分布式任务调度

分布式任务调度的优点

  • 高可用。在集群架构下,有节点出现异常,不影响任务的执行。
  • 动态配置。对任务的执行周期,以及其他跟任务相关的属性不停机修改。
  • 生命周期管理。可以在不停机的情况下,对任务单次执行启动任务,关闭任务的管理。
  • 失败机制。在任务执行过程中出现执行失败时,支持报警、任务重试并快速查阅执行日志。
  • 数据统计。在定时任务数比较多的情况下,支持统计一共有多少任务,哪些任务执行失败过,哪些任务执行成功。
  • 分片执行。对于批量处理的数据,让多台机器执行该任务,对数据进行分片处理。

分布式任务调度解决方案

由于集中式的定时任务调度需要解决一系列问题,所以在技术演进的过程中产生一些解决办法:

  • 使用数据库唯一约束
  • 使用配置文件、Redis、MySQL 作为任务调度的开关
  • 使用分布式锁实现任务调度的并发控制
  • 使用开源的分布式任务调度平台 TBSchedule、Elastic-Job、Saturn、XXL-JOB 等
  • 自研分布式任务调度平台

分布式任务调度开源框架

XXL-JOB

XXL-JOB 是美团开源的轻量级分布式任务调度平台,其核心设计目标是轻量级、易扩展、开发迅速、开箱即用,已有多家公司线上产品线采用了 XXL-JOB。

Elastic-Job

Elastic-Job 是当当网推出的分布式任务调度框架,现在已经被纳入到 Apache 基金会下,很多公司的产品都在使用该分布式任务调度框架。

PowerJob

PowerJob 是新一代分布式任务调度与计算框架,支持 CRON、API、固定频率、固定延迟等调度策略,提供工作流来编排任务解决依赖关系,使用简单,功能强大。

Saturn

Saturn 唯品会推出的开源分布式任务调度平台,它是基于 Elastic-Job 而开发的,新增了一些特性,唯品会内部及一些互联网公司都在使用,但目前项目处于停止维护的状态。

IDEA 运行 XXL-JOB 调度中心

XXL-JOB 由调度中心(服务端)和执行器(客户端)两个核心模块组成,因此一般需要先运行调度中心的服务,然后再开发执行器(客户端)的业务代码。

下载源码项目

1
2
3
4
5
# GitHub
$ git clone https://github.com/xuxueli/xxl-job.git

# Gitee
$ git clone https://github.com/xuxueli/xxl-job.git

导入源码项目

将源码项目导入到 IDEA 中,方便快速启动 XXL-JOB 的调度中心和阅读底层源码。

初始化数据库

为了初始化调度中心的数据库,需要在数据库里执行源码项目中的 SQL 脚本,文件路径是 /xxl-job/doc/db/tables_xxl_job.sql。值得一提的是,数据库初始化完成之后,一共有 8 张表

表名称描述
xxl_job_group 执行器信息表,用于维护任务执行器的信息
xxl_job_info 调度扩展信息表,用于存储调度任务的扩展信息,比如任务分组、任务名、机器的地址等
xxl_job_lock 任务调度锁表
xxl_job_log 日志表,用于存储任务调度的历史信息,例如调度结果、执行结果、调度入参等
xxl_job_log_report 日志报表,用于存储任务调度的日志报表,会在调度中心里的报表功能里使用到
xxl_job_logglue 任务的 GLUE 日志,用于存储 GLUE 日志的更新历史变化,支持 GLUE 版本的回溯功能
xxl_job_registry 执行器的注册表,用在维护在线的执行器与调度中心的地址信息
xxl_job_user 系统的用户表,可以用表中默认的用户名与密码进行登录

更改配置信息

打开 xxl-job-admin 模块下的 application.properties 配置文件,更改数据库的连接信息。

1
2
3
4
5
### xxl-job, datasource
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

启动调度中心

打开 xxl-job-admin 模块下的 XxlJobAdminApplication 主启动类,在 IDEA 内直接启动调度中心的服务。

登录调度中心

浏览器访问 http://127.0.0.1:8080/xxl-job-admin,默认登录的账号密码是 admin / 123456

提示

  1. 若浏览器能正常访问调度中心的管理页面,则说明 XXL-JOB 的调度中心启动成功。
  2. XXL-JOB 调度中心的前端页面使用了 AdminLTE 框架,它是一个基于 Bootstrap 框架和 jQuery 插件的开源的管理模板工具,提供了一系列响应迅速的、可重复使用的组件,并设置了许多模板页面。

Docker 运行 XXL-JOB 调度中心