SpringBoot 整合 XXL-JOB——分布式任务调度实战
@Scheduled 在单机环境下够用,但多实例部署时会遇到同一个任务每个机器都执行一遍的问题。XXL-JOB 是一个分布式任务调度平台,提供可视化任务管理、执行日志、失败告警等能力,是生产环境的主流选择。
一、XXL-JOB 架构
调度中心(xxl-job-admin) │ 调度任务 ↓ ├── 执行器 A(任务1、任务2) ├── 执行器 B(任务1、任务3) └── 执行器 C(任务2、任务4)核心概念:
- 调度中心:管理任务配置、触发调度、查看日志
- 执行器:实际执行任务的应用程序
- 任务:具体的业务逻辑
二、部署调度中心
1. 下载源码
gitclone https://github.com/xuxueli/xxl-job.git2. 初始化数据库
-- 执行 xxl-job/doc/db/tables_xxl_job.sql-- 会创建 xxl_job 数据库及相关表3. 修改配置
# xxl-job-admin/src/main/resources/application.propertiesserver.port=8080 spring.datasource.url=jdbc:mysql://localhost:3306/xxl_job?useUnicode=true&characterEncoding=utf-8spring.datasource.username=root spring.datasource.password=123456# 登录账号xxl.job.login.username=admin xxl.job.login.password=1234564. 启动
mvn clean package-DskipTestsjava-jarxxl-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-adminexecutor:# 执行器名称appname:seckill-executor# 执行器端口port:9999# 执行器注册地址address:""ip:""logpath:/data/xxl-job/logslogretentiondays:30accessToken:# 调度中心通信 Token3. 配置类
@ConfigurationpublicclassXxlJobConfig{@Value("${xxl.job.admin.addresses}")privateStringadminAddresses;@Value("${xxl.job.executor.appname}")privateStringappname;@Value("${xxl.job.executor.port}")privateintport;@BeanpublicXxlJobSpringExecutorxxlJobExecutor(){XxlJobSpringExecutorexecutor=newXxlJobSpringExecutor();executor.setAdminAddresses(adminAddresses);executor.setAppname(appname);executor.setPort(port);executor.setLogPath("/data/xxl-job/logs");executor.setLogRetentionDays(30);returnexecutor;}}四、编写任务
1. Bean 模式(推荐)
@ComponentpublicclassSeckillTasks{privatestaticfinalLoggerlog=LoggerFactory.getLogger(SeckillTasks.class);/** * 超时未支付订单处理 */@XxlJob("timeoutOrderHandler")publicReturnT<String>timeoutOrderHandler(Stringparam){log.info("开始处理超时未支付订单...");// 查询超时订单List<Order>timeoutOrders=orderService.list(newLambdaQueryWrapper<Order>().eq(Order::getStatus,0).lt(Order::getCreateTime,LocalDateTime.now().minusMinutes(10)));for(Orderorder:timeoutOrders){// 取消订单order.setStatus(2);orderService.updateById(order);// 归还库存productService.restoreStock(order.getProductId(),order.getQuantity());}log.info("处理完成,共取消 {} 笔订单",timeoutOrders.size());returnReturnT.SUCCESS;}/** * 每日数据统计 */@XxlJob("dailyReport")publicReturnT<String>dailyReport(Stringparam){log.info("生成日报表...");// 报表生成逻辑returnReturnT.SUCCESS;}}2. 分片广播模式(多机器协作)
适合大数据量处理,把数据分给多个执行器并行处理:
@XxlJob("shardingJob")publicReturnT<String>shardingJob(Stringparam){// 获取当前执行器的分片信息ShardingUtil.ShardingVOshardingVO=ShardingUtil.getShardingVo();intindex=shardingVO.getIndex();// 当前执行器编号(从0开始)inttotal=shardingVO.getTotal();// 执行器总数// 查询所有需要处理的数据List<Long>userIds=getAllUserIds();// 只处理分配给自己的那部分for(inti=index;i<userIds.size();i+=total){processUser(userIds.get(i));}log.info("分片 {}/{} 处理完成,处理 {} 条",index+1,total,userIds.size()/total);returnReturnT.SUCCESS;}五、在管理台配置任务
登录调度中心 → 执行器管理 → 新增执行器:
AppName: seckill-executor 名称: 秒杀系统执行器 注册方式: 自动注册任务管理 → 新增任务:
执行器: seckill-executor 任务描述: 超时订单处理 调度类型: cron Cron: 0 */1 * * * ? ← 每分钟执行一次 运行模式: Bean JobHandler: timeoutOrderHandler六、任务参数传递
@XxlJob("paramJob")publicReturnT<String>paramJob(Stringparam){// param 是在调度中心配置任务时填写的参数log.info("接收参数: {}",param);if(StringUtils.isNotBlank(param)){JSONObjectjson=JSONObject.parseObject(param);Stringdate=json.getString("date");intlimit=json.getInteger("limit");// 使用参数执行任务}returnReturnT.SUCCESS;}在调度中心的任务配置中填入 JSON 参数:
{"date":"2026-07-03","limit":1000}七、任务执行日志
@XxlJob("logJob")publicReturnT<String>logJob(Stringparam){XxlJobLogger.log("任务开始执行...");try{// 业务逻辑XxlJobLogger.log("处理第 1 批数据,共 100 条");Thread.sleep(1000);XxlJobLogger.log("处理第 2 批数据,共 100 条");Thread.sleep(1000);XxlJobLogger.log("任务执行完成");returnReturnT.SUCCESS;}catch(Exceptione){XxlJobLogger.log("任务执行失败: {}",e.getMessage());returnReturnT.FAIL;}}在调度中心可以实时查看每台机器上的任务执行日志。
八、@Scheduled vs Quartz vs XXL-JOB
| 对比 | @Scheduled | Quartz | XXL-JOB |
|---|---|---|---|
| 部署 | 内嵌 | 内嵌 | 调度中心 + 执行器分离 |
| 可视化 | ❌ | ❌ | ✅ 管理界面 |
| 分布式 | ❌ 每个实例都执行 | ❌ 需自己实现 | ✅ 天然支持 |
| 失败告警 | ❌ | ❌ | ✅ 邮件告警 |
| 动态修改 | ❌ 改代码重启 | ❌ | ✅ 在线修改 |
| 适用场景 | 简单单机任务 | 复杂调度逻辑 | 生产环境分布式 |
九、秒杀系统集成建议
每天零点 → 清理过期活动数据 → 日清理任务 每分钟 → 检查超时未支付订单 → 超时订单处理 每月1号 → 生成月度报表 → 月报任务 大促后 → 数据归档 → 归档任务(分片广播)建议:项目初期用 @Scheduled 快速实现,等系统上线稳定后再迁移到 XXL-JOB。
💡 觉得有用的话,点赞 + 关注【张老师技术栈】吧!每周更新 Java/Python/爬虫 实战干货,不让你白来。
