SpringBoot整合XXL-JOB实现分布式任务调度的实战指南
作者:张老师技术栈
XXL-JOB 是一个分布式任务调度平台,提供可视化任务管理、执行日志、失败告警等能力,是生产环境的主流选择,本文给大家介绍了SpringBoot整合XXL-JOB实现分布式任务调度的实战指南,需要的朋友可以参考下
@Scheduled 在单机环境下够用,但多实例部署时会遇到同一个任务每个机器都执行一遍的问题。XXL-JOB 是一个分布式任务调度平台,提供可视化任务管理、执行日志、失败告警等能力,是生产环境的主流选择。
一、XXL-JOB 架构
调度中心(xxl-job-admin)
│ 调度任务 ↓
├── 执行器 A(任务1、任务2)
├── 执行器 B(任务1、任务3)
└── 执行器 C(任务2、任务4)
核心概念:
- 调度中心:管理任务配置、触发调度、查看日志
- 执行器:实际执行任务的应用程序
- 任务:具体的业务逻辑
二、部署调度中心
1. 下载源码
git clone https://github.com/xuxueli/xxl-job.git
2. 初始化数据库
-- 执行 xxl-job/doc/db/tables_xxl_job.sql -- 会创建 xxl_job 数据库及相关表
3. 修改配置
# xxl-job-admin/src/main/resources/application.properties server.port=8080 spring.datasource.url=jdbc:mysql://localhost:3306/xxl_job?useUnicode=true&characterEncoding=utf-8 spring.datasource.username=root spring.datasource.password=123456 # 登录账号 xxl.job.login.username=admin xxl.job.login.password=123456
4. 启动
mvn clean package -DskipTests java -jar xxl-job-admin/target/xxl-job-admin-2.4.0.jar
访问 http://localhost:8080/xxl-job-admin,登录后即可看到管理界面。
三、SpringBoot 集成执行器
1. 引入依赖
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>2.4.0</version>
</dependency>2. 配置
xxl:
job:
admin:
# 调度中心地址
addresses: http://localhost:8080/xxl-job-admin
executor:
# 执行器名称
appname: seckill-executor
# 执行器端口
port: 9999
# 执行器注册地址
address: ""
ip: ""
logpath: /data/xxl-job/logs
logretentiondays: 30
accessToken: # 调度中心通信 Token3. 配置类
@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;
@Bean
public XxlJobSpringExecutor xxlJobExecutor() {
XxlJobSpringExecutor executor = new XxlJobSpringExecutor();
executor.setAdminAddresses(adminAddresses);
executor.setAppname(appname);
executor.setPort(port);
executor.setLogPath("/data/xxl-job/logs");
executor.setLogRetentionDays(30);
return executor;
}
}
四、编写任务
1. Bean 模式(推荐)
@Component
public class SeckillTasks {
private static final Logger log = LoggerFactory.getLogger(SeckillTasks.class);
/**
* 超时未支付订单处理
*/
@XxlJob("timeoutOrderHandler")
public ReturnT<String> timeoutOrderHandler(String param) {
log.info("开始处理超时未支付订单...");
// 查询超时订单
List<Order> timeoutOrders = orderService.list(
new LambdaQueryWrapper<Order>()
.eq(Order::getStatus, 0)
.lt(Order::getCreateTime, LocalDateTime.now().minusMinutes(10))
);
for (Order order : timeoutOrders) {
// 取消订单
order.setStatus(2);
orderService.updateById(order);
// 归还库存
productService.restoreStock(order.getProductId(), order.getQuantity());
}
log.info("处理完成,共取消 {} 笔订单", timeoutOrders.size());
return ReturnT.SUCCESS;
}
/**
* 每日数据统计
*/
@XxlJob("dailyReport")
public ReturnT<String> dailyReport(String param) {
log.info("生成日报表...");
// 报表生成逻辑
return ReturnT.SUCCESS;
}
}
2. 分片广播模式(多机器协作)
适合大数据量处理,把数据分给多个执行器并行处理:
@XxlJob("shardingJob")
public ReturnT<String> shardingJob(String param) {
// 获取当前执行器的分片信息
ShardingUtil.ShardingVO shardingVO = ShardingUtil.getShardingVo();
int index = shardingVO.getIndex(); // 当前执行器编号(从0开始)
int total = shardingVO.getTotal(); // 执行器总数
// 查询所有需要处理的数据
List<Long> userIds = getAllUserIds();
// 只处理分配给自己的那部分
for (int i = index; i < userIds.size(); i += total) {
processUser(userIds.get(i));
}
log.info("分片 {}/{} 处理完成,处理 {} 条", index + 1, total,
userIds.size() / total);
return ReturnT.SUCCESS;
}
五、在管理台配置任务
登录调度中心 → 执行器管理 → 新增执行器:
AppName: seckill-executor 名称: 秒杀系统执行器 注册方式: 自动注册
任务管理 → 新增任务:
执行器: seckill-executor 任务描述: 超时订单处理 调度类型: cron Cron: 0 */1 * * * ? ← 每分钟执行一次 运行模式: Bean JobHandler: timeoutOrderHandler
六、任务参数传递
@XxlJob("paramJob")
public ReturnT<String> paramJob(String param) {
// param 是在调度中心配置任务时填写的参数
log.info("接收参数: {}", param);
if (StringUtils.isNotBlank(param)) {
JSONObject json = JSONObject.parseObject(param);
String date = json.getString("date");
int limit = json.getInteger("limit");
// 使用参数执行任务
}
return ReturnT.SUCCESS;
}
在调度中心的任务配置中填入 JSON 参数:
{"date": "2026-07-03", "limit": 1000}七、任务执行日志
@XxlJob("logJob")
public ReturnT<String> logJob(String param) {
XxlJobLogger.log("任务开始执行...");
try {
// 业务逻辑
XxlJobLogger.log("处理第 1 批数据,共 100 条");
Thread.sleep(1000);
XxlJobLogger.log("处理第 2 批数据,共 100 条");
Thread.sleep(1000);
XxlJobLogger.log("任务执行完成");
return ReturnT.SUCCESS;
} catch (Exception e) {
XxlJobLogger.log("任务执行失败: {}", e.getMessage());
return ReturnT.FAIL;
}
}
在调度中心可以实时查看每台机器上的任务执行日志。
八、@Scheduled vs Quartz vs XXL-JOB
| 对比 | @Scheduled | Quartz | XXL-JOB |
|---|---|---|---|
| 部署 | 内嵌 | 内嵌 | 调度中心 + 执行器分离 |
| 可视化 | ❌ | ❌ | ✅ 管理界面 |
| 分布式 | ❌ 每个实例都执行 | ❌ 需自己实现 | ✅ 天然支持 |
| 失败告警 | ❌ | ❌ | ✅ 邮件告警 |
| 动态修改 | ❌ 改代码重启 | ❌ | ✅ 在线修改 |
| 适用场景 | 简单单机任务 | 复杂调度逻辑 | 生产环境分布式 |
九、秒杀系统集成建议
每天零点 → 清理过期活动数据 → 日清理任务 每分钟 → 检查超时未支付订单 → 超时订单处理 每月1号 → 生成月度报表 → 月报任务 大促后 → 数据归档 → 归档任务(分片广播)
建议: 项目初期用 @Scheduled 快速实现,等系统上线稳定后再迁移到 XXL-JOB。
以上就是SpringBoot整合XXL-JOB实现分布式任务调度的实战指南的详细内容,更多关于SpringBoot XXL-JOB分布式任务调度的资料请关注脚本之家其它相关文章!
