1. 为什么选择xxl-job与SpringBoot集成
在微服务架构中,定时任务是个绕不开的需求。你可能尝试过用Spring自带的@Scheduled注解,但当任务多了就会发现:没有可视化界面、无法动态调整执行时间、任务执行情况难以追踪...这些问题xxl-job都能完美解决。
我去年接手的一个电商项目就遇到过典型场景:每天凌晨要跑几十个定时任务,有清理临时文件的、有生成报表的、有同步第三方数据的。最初用Spring Task硬编码,结果每次修改执行时间都要重新发布服务,运维同事差点提刀来找我。换成xxl-job后,所有任务配置都能在网页端动态调整,还能看到每次执行的详细日志,团队效率直接翻倍。
xxl-job的核心优势在于:
- 可视化调度:像操作Excel一样管理所有任务
- 失败重试:自动记录失败任务并重试
- 执行日志:每个任务的生命周期全程可追溯
- 路由策略:支持轮询、随机、故障转移等智能调度
2. 5分钟快速集成指南
2.1 引入必要依赖
在你的SpringBoot项目的pom.xml中添加这些依赖(建议用最新稳定版):
<!-- xxl-job核心依赖 --> <dependency> <groupId>com.xuxueli</groupId> <artifactId>xxl-job-core</artifactId> <version>2.3.1</version> </dependency> <!-- 如果用到Spring Cloud --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency>注意一个小坑:xxl-job 2.3.0+版本开始支持JDK11+,如果你还在用JDK8,建议使用2.2.0版本。
2.2 配置执行器参数
在application.yml中添加这些配置(记得替换成你的实际参数):
xxl: job: admin: addresses: http://你的调度中心地址:8080/xxl-job-admin executor: appname: your-app-name # 建议用项目名 ip: port: 9999 # 默认端口,冲突可改 logpath: /data/applogs/xxl-job/jobhandler logretentiondays: 30 accessToken: # 如果调度中心配置了token要填遇到过最奇葩的配置错误是有人把addresses写成单数address,导致一直连接不上调度中心。另外建议appname用英文,中文可能会有编码问题。
3. 编写第一个任务Handler
3.1 基础任务示例
创建一个简单的统计任务:
@XxlJob("demoJobHandler") public void demoJobHandler() throws Exception { XxlJobHelper.log("任务开始执行"); // 模拟业务处理 for (int i = 0; i < 5; i++) { XxlJobHelper.log("处理第{}条数据", i); TimeUnit.SECONDS.sleep(1); } // 默认返回成功,失败可抛异常 }几个关键点:
- 方法必须用
@XxlJob注解 - 通过
XxlJobHelper.log()记录日志 - 抛出异常即视为任务失败
3.2 带参数的任务
实际业务中经常需要动态参数:
@XxlJob("paramJobHandler") public void paramJobHandler() { // 获取调度参数 String param = XxlJobHelper.getJobParam(); // 参数解析示例 if(StringUtils.isNotBlank(param)){ String[] params = param.split(","); // 业务处理... } XxlJobHelper.handleSuccess("处理完成,参数:" + param); }在调度中心创建任务时,可以在"任务参数"栏填写2023-01-01,100这样的参数,任务中就能获取到。
4. 调度中心对接实战
4.1 执行器自动注册
最新版xxl-job支持两种注册方式:
- 手动录入:在调度中心管理后台手动添加执行器地址
- 自动注册(推荐):执行器启动后自动注册
要实现自动注册,确保配置正确:
xxl: job: executor: address:留空address就会启用自动注册。遇到过有人填了IP反而注册失败的情况,这时候注释掉这行就好了。
4.2 任务配置技巧
在调度中心创建任务时,这几个参数最易出错:
- 路由策略:简单场景用"轮询",需要容错用"故障转移"
- 运行模式:SpringBoot项目选"BEAN"
- 阻塞处理策略:高优先级任务选"丢弃后续调度"
- 超时时间:根据任务实际耗时设置,别用默认的0(不限制)
特别提醒:任务超时是最常见的线上问题之一。有次我们的报表任务因为SQL没优化,执行了2小时,直接把线程池占满。后来设置了30分钟超时,超时后自动告警。
5. 生产环境避坑指南
5.1 日志排查技巧
当任务执行失败时,按这个顺序排查:
- 调度中心"任务日志"查看详细报错
- 检查执行器本地日志文件(配置的logpath)
- 查看服务器磁盘空间(遇到过日志把磁盘写满的情况)
一个实用命令查看最近错误:
grep -A 10 "ERROR" /data/applogs/xxl-job/jobhandler/*.log | tail -n 505.2 性能优化建议
- 线程池配置:默认corePoolSize=2,高并发场景需要调整
xxl: job: executor: max-pool-size: 10- DB连接池:如果用了Druid,记得单独配置xxl-job的数据源
- 日志清理:设置合理的logretentiondays,避免日志爆炸
6. 高级功能拓展
6.1 分片广播任务
处理大数据量的神器,比如要处理100万条数据:
@XxlJob("shardingJobHandler") public void shardingJobHandler() { // 获取分片参数 int shardIndex = XxlJobHelper.getShardIndex(); int shardTotal = XxlJobHelper.getShardTotal(); // 根据分片处理数据 List<Long> dataIds = queryDataIds(); for(int i=0; i<dataIds.size(); i++){ if(i % shardTotal == shardIndex){ processData(dataIds.get(i)); } } }在调度中心创建任务时,选择"分片广播"路由策略,所有执行器都会收到任务,但只处理属于自己的那部分数据。
6.2 父子任务依赖
通过"子任务Key"配置可以实现任务依赖,比如:
- 任务A:每天0点清理临时数据
- 任务B:依赖A执行完成后,开始统计报表
配置时在任务A的"子任务Key"中填写任务B的JobKey即可。注意要避免循环依赖,否则会导致任务死锁。