XXL-Job【一、简介】
XXL-JOB 完整版详解:调度原理 + 核心架构 + 内置工具类 + 部署集成 + 控制台配置 + 生产实践
一、XXL-JOB 整体概述
XXL-JOB 是轻量级分布式任务调度框架,核心架构:调度中心(Admin) + 执行器(Executor),具备去中心化注册、动态调度、故障转移、分片广播、日志溯源、失败告警等能力,开箱即用、无侵入、适配 SpringBoot 微服务。
核心优势:
- 支持 CRON 定时、固定速率、一次性任务;
- 执行器自动注册发现,集群负载均衡;
- 调度中心集群高可用,数据库锁防重复调度;
- 内置日志、分片、任务终止、参数获取等工具类;
- 支持任务阻塞策略、失败重试、超时控制、钉钉/邮件告警。
二、XXL-JOB 核心调度原理
2.1 核心角色分工
| 角色 | 职责 | 部署特点 |
|---|---|---|
| 调度中心 xxl-job-admin | 任务管理、CRON 解析、任务触发、日志存储、告警、执行器注册监控 | 集群部署,共享MySQL,无业务逻辑 |
| 执行器 Executor | 嵌入业务项目,接收调度指令、执行具体业务任务、上报心跳与执行结果 | 多实例集群,同AppName自动负载 |
2.2 注册与心跳机制
- 执行器启动后,主动向调度中心注册自身信息(AppName、IP、端口);
- 执行器每30s上报一次心跳;
- 调度中心每60s扫描注册表,90s 无心跳判定执行器离线并剔除;
- 通信基于 Netty HTTP,默认执行器端口
9999。
2.3 核心调度执行流程
- 定时扫描:调度中心后台线程每秒轮询任务表,筛选待触发任务;
- 时间轮预加载:采用秒级时间轮缓存未来5s待执行任务,减少DB查询压力;
- 集群防重:调度中心多节点通过 MySQL 悲观锁
select ... for update,保证同一任务只被一个节点触发; - 路由选择:根据配置路由策略(轮询、随机、一致性哈希、分片广播等)选中一台在线执行器;
- 远程调用:调度中心通过 HTTP 下发执行指令到目标执行器;
- 任务执行:执行器匹配
@XxlJob标记的任务处理器,放入内置线程池异步执行; - 结果回调:任务执行完毕,执行器异步回调执行状态、日志给调度中心;
- 日志持久化&告警:调度中心记录执行日志,失败则触发重试、钉钉/邮件告警。
2.4 高可用核心机制
- 调度中心HA:多节点集群 + 同库悲观锁,避免任务重复调度;
- 执行器HA:同AppName多实例,节点宕机自动路由到存活节点;
- 任务容错:支持失败重试、超时终止、三种阻塞策略(单机串行、丢弃后续调度、覆盖之前调度)。
三、XXL-JOB 内置核心工具类完整使用示例
依赖导入后,直接在任务方法中使用以下官方工具类。
3.1 日志工具:XxlJobLogger
日志可在调度中心控制台在线查看,替代 System.out
import com.xxl.job.core.log.XxlJobLogger;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.xxl.job.core.biz.model.ReturnT;
import org.springframework.stereotype.Component;
@Component
public class DemoTask {
@XxlJob("loggerDemoTask")
public ReturnT<String> loggerDemoTask(String taskParam) {
// 普通日志
XxlJobLogger.log("任务开始执行");
// 带参数占位打印
XxlJobLogger.log("接收任务参数:{}", taskParam);
// 异常堆栈打印
try {
int i = 1 / 0;
} catch (Exception e) {
XxlJobLogger.log(e, "业务执行异常");
}
return ReturnT.SUCCESS;
}
}
3.2 任务上下文工具:XxlJobHelper
3.2.1 获取分片信息(大数据分片并行必备)
@XxlJob("shardTask")
public ReturnT<String> shardTask(String param) {
// 当前分片索引:从0开始
int shardIndex = XxlJobHelper.getShardIndex();
// 总分片数量(等于在线执行器节点数)
int shardTotal = XxlJobHelper.getShardTotal();
XxlJobLogger.log("分片执行:当前{}/{}", shardIndex, shardTotal);
// 业务场景:根据id取模分片 id % shardTotal == shardIndex
return ReturnT.SUCCESS;
}
3.2.2 任务终止判断
手动停止任务时,可感知并优雅退出
@XxlJob("stopCheckTask")
public ReturnT<String> stopCheckTask(String param) {
for (int i = 0; i < 100; i++) {
// 判断是否被手动终止
if (XxlJobHelper.isStopped()) {
XxlJobLogger.log("任务被手动终止,退出执行");
return ReturnT.FAIL;
}
// 模拟业务处理
XxlJobLogger.log("执行进度:{}", i);
}
return ReturnT.SUCCESS;
}
3.2.3 获取任务元信息
// 当前任务ID
long jobId = XxlJobHelper.getJobId();
// 调度触发时间
Date triggerTime = XxlJobHelper.getTriggerTime();
// 获取任务自定义参数
String taskParams = XxlJobHelper.getJobParam();
3.3 任务返回值规范
// 执行成功
return ReturnT.SUCCESS;
// 执行失败,触发重试+告警
return ReturnT.FAIL;
// 失败并返回自定义描述
return new ReturnT<>(ReturnT.FAIL_CODE, "数据同步失败:数据库连接异常");
四、完整部署与 SpringBoot 集成实战
4.1 环境依赖
- JDK 1.8+
- MySQL 5.7 / 8.0
- SpringBoot 2.x / 3.x
- XXL-JOB 版本:
2.4.0(稳定通用版)
4.2 初始化数据库
- 下载 XXL-JOB 源码:https://github.com/xuxueli/xxl-job
- 执行脚本:
xxl-job/doc/db/tables_xxl_job.sql - 自动创建 8 张系统表,核心表:
xxl_job_info:任务配置表xxl_job_registry:执行器注册表xxl_job_log:任务执行日志表
4.3 部署调度中心 xxl-job-admin
4.3.1 修改配置 application.properties
# 服务端口
server.port=8080
server.servlet.context-path=/xxl-job-admin
# 数据源配置
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl_job?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowMultiQueries=true
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 通信令牌(执行器必须和这里一致)
xxl.job.accessToken=default_token
4.3.2 启动访问
- 启动
XxlJobAdminApplication - 访问地址:
http://localhost:8080/xxl-job-admin - 默认账号密码:
admin / 123456
4.4 SpringBoot 项目集成执行器
4.4.1 Maven 依赖
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>2.4.0</version>
</dependency>
4.4.2 配置文件 application.yml
xxl:
job:
# 调度中心地址,集群用逗号分隔
admin:
addresses: http://127.0.0.1:8080/xxl-job-admin
# 执行器配置
executor:
appname: xxl-job-business-demo
port: 9999
logpath: /data/xxl-job/logs
logretentiondays: 30
# 通信令牌
access-token: default_token
4.4.3 执行器配置类
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
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.executor.logpath}")
private String logPath;
@Value("${xxl.job.executor.logretentiondays}")
private int logRetentionDays;
@Value("${xxl.job.access-token}")
private String accessToken;
@Bean
public XxlJobSpringExecutor xxlJobSpringExecutor() {
XxlJobSpringExecutor executor = new XxlJobSpringExecutor();
executor.setAdminAddresses(adminAddresses);
executor.setAppname(appName);
executor.setPort(port);
executor.setLogPath(logPath);
executor.setLogRetentionDays(logRetentionDays);
executor.setAccessToken(accessToken);
return executor;
}
}
4.4.4 编写业务任务
@Component
public class BusinessTask {
@XxlJob("cronTaskHandler")
public ReturnT<String> cronTaskHandler(String param) {
XxlJobLogger.log("CRON定时任务执行,参数:{}", param);
// 自定义业务逻辑
return ReturnT.SUCCESS;
}
}
五、调度中心控制台完整配置步骤
5.1 新增执行器
执行器管理 → 新增
- 执行器AppName:
xxl-job-business-demo(和配置文件一致) - 名称:业务演示执行器
- 注册方式:自动注册
- 保存后可看到在线执行器节点信息
5.2 新增定时任务
任务管理 → 新增
- 执行器:选择上面创建的执行器
- 任务描述:测试定时任务
- 调度类型:CRON
- Cron表达式:
*/5 * * * * ?每5秒执行一次 - 路由策略:轮询
- JobHandler:
cronTaskHandler(和@XxlJob注解名称完全一致) - 任务参数:自定义传入参数
- 阻塞策略:单机串行
- 失败重试次数:3次
- 保存后启动任务
5.3 查看执行日志
任务列表 → 操作 → 日志,可查看执行记录、自定义日志、异常堆栈。
六、集群部署与生产最佳实践
6.1 调度中心集群
- 多节点部署
xxl-job-admin,连接同一个MySQL; - 前端配置 Nginx 负载均衡,所有执行器配置 Nginx 地址;
- 依靠数据库悲观锁天然实现任务互斥,无需额外改造。
6.2 执行器集群
- 多个业务实例配置相同 AppName;
- 调度中心自动感知,按路由策略负载均衡;
- 某节点宕机自动剔除,任务路由到其他节点。
6.3 生产规范
- 任务必须做幂等性,防止重试导致数据重复;
- 长耗时任务拆分,避免单任务阻塞线程池;
- 统一使用
XxlJobLogger打印日志,方便线上排查; - 大数据量同步优先使用分片广播;
- 配置任务失败钉钉/企业微信/邮件告警;
- 合理设置任务超时时间、阻塞策略、重试次数。
七、常见问题排查
- 执行器无法注册
- 检查调度中心地址、accessToken 是否一致;
- 服务器防火墙放行 8080、9999 端口;
- 任务配置正确但不执行
- JobHandler 名称和注解不一致;
- 任务未手动启动;
- CRON 表达式格式错误;
- 任务重复执行
- 调度中心集群未共用同一个数据库;
- 数据库锁机制失效;
- 日志看不到自定义打印
- 必须使用
XxlJobLogger,不能用原生日志框架。
- 必须使用
本文来自博客园,作者:蓝迷梦,转载请注明原文链接:https://www.cnblogs.com/hewei-blogs/articles/20021091

浙公网安备 33010602011771号