springcloud xxl-job
针对你的需求,这里整理了一份从 Docker 部署调度中心(Admin)、SpringBoot 执行器开发、控制台配置到分片广播实战的全流程指南。
一、Docker 部署调度中心 (xxl-job-admin)
这是任务调度的“大脑”,需要依赖 MySQL 数据库。
1. 数据库初始化
首先在 MySQL 中创建数据库xxl_job,并执行https://github.com/xuxueli/xxl-job/blob/master/doc/db/tables_xxl_job.sql初始化表结构。
2. Docker 启动 Admin
使用官方镜像xuxueli/xxl-job-admin:2.4.0启动容器。注意:PARAMS中的数据库连接 IP 需使用 Docker 网络内的 MySQL 容器 IP 或服务名(非 127.0.0.1)。
# 拉取镜像dockerpull xuxueli/xxl-job-admin:2.4.0# 运行容器(请替换为你实际的 MySQL 连接信息)# 停止并移除旧容器dockerstop xxl-job-admin1dockerrmxxl-job-admin1dockerrun-d\--namexxl-job-admin\-p9080:8080\-v/tmp/xxl-job-logs:/data/applogs\-ePARAMS="--spring.datasource.url=jdbc:mysql://10.10.1.45:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false --spring.datasource.username=root --spring.datasource.password=root"\xuxueli/xxl-job-admin:2.4.0启动后访问http://服务器IP:8080/xxl-job-admin,默认账号admin/123456。
二、SpringBoot 执行器开发
执行器是承载具体任务逻辑的业务服务。
1. 项目依赖 (pom.xml)
<dependency><groupId>com.xuxueli</groupId><artifactId>xxl-job-core</artifactId><version>2.4.0</version></dependency>2. 配置文件 (application.yml)
xxl:job:admin:addresses:http://你的Admin服务器IP:8080/xxl-job-admin# 调度中心地址accessToken:你的Token# 若调度中心配置了Token,此处需一致executor:appname:xxl-job-executor-demo# 必须与Admin控制台执行器AppName一致port:9999# 执行器端口,需未被占用logpath:./logs/xxl-job/jobhandlerlogretentiondays:303. 配置类与任务开发
@ConfigurationpublicclassXxlJobConfig{@Value("${xxl.job.admin.addresses}")privateStringadminAddresses;// ... 其他配置项(accessToken, appname等)@BeanpublicXxlJobSpringExecutorxxlJobExecutor(){XxlJobSpringExecutorexecutor=newXxlJobSpringExecutor();executor.setAdminAddresses(adminAddresses);executor.setAppname(appname);executor.setPort(port);returnexecutor;}}@ComponentpublicclassDemoJobHandler{// 1. 简单任务示例@XxlJob("demoJobHandler")publicvoiddemoJobHandler()throwsException{XxlJobHelper.log("简单任务执行成功");// 你的业务逻辑...}// 2. 分片任务示例(详见第四节)@XxlJob("shardingJobHandler")publicvoidshardingJobHandler()throwsException{intshardIndex=XxlJobHelper.getShardIndex();// 当前分片号(从0开始)intshardTotal=XxlJobHelper.getShardTotal();// 总分片数// 模拟处理:只有当前分片处理对应数据if(/* 数据ID % shardTotal == shardIndex */){// 处理该分片的数据}}}三、调度中心控制台配置
1. 配置执行器
路径:执行器管理->新增
- AppName:必须与项目配置文件中的
xxl.job.executor.appname完全一致(如xxl-job-executor-demo)。 - 注册方式:推荐选择自动注册(执行器启动后会自动上报地址)。
2. 配置任务
路径:任务管理->新增
- 执行器:选择上一步创建的执行器。
- JobHandler:填写代码中
@XxlJob注解的值(如demoJobHandler)。 - 路由策略:
- 单机/负载均衡:选择
FIRST(首台)或ROUND(轮询)。 - 分片处理:必须选择分片广播(SHARDING_BROADCAST)。
- 单机/负载均衡:选择
- Cron:设置调度表达式。
- 运行模式:选择
BEAN。
四、分片广播开发详解
分片广播是解决海量数据并行处理的核心方案。其原理是:调度中心一次调度,所有在线的执行器实例都会同时被触发,每个实例通过shardIndex和shardTotal区分各自处理的数据区间。
1. 核心代码逻辑
@XxlJob("hugeDataJobHandler")publicvoidhugeDataJobHandler()throwsException{intindex=XxlJobHelper.getShardIndex();inttotal=XxlJobHelper.getShardTotal();// 1. 查询总数据量(所有分片查询逻辑一致)intallDataCount=orderMapper.selectCount();// 2. 计算当前分片负责的数据范围(取模分片法)List<Order>currentShardData=orderMapper.selectByShard(index,total);// 3. 处理当前分片的数据for(Orderorder:currentShardData){// 业务处理...}XxlJobHelper.log("分片[{}/{}]处理完成,共处理{}条",index,total,currentShardData.size());}2. 数据分片策略(SQL示例)
假设有 1000 条数据,有 2 个执行器(分片总数 total=2):
- 执行器A(index=0):处理 ID % 2 == 0 的数据(偶数ID)。
- 执行器B(index=1):处理 ID % 2 == 1 的数据(奇数ID)。
对应的 MyBatis SQL 映射:
<selectid="selectByShard"resultType="Order">SELECT * FROM order_table WHERE MOD(id, #{total}) = #{index} AND status = 'PENDING'</select>3. 关键注意事项
- 幂等性:分片任务可能因重试等原因重复执行,业务逻辑需保证幂等。
- 数据倾斜:若使用取模分片,确保数据ID分布均匀,避免某个分片数据量过大。
- 动态扩容:执行器实例数变化(total变化)时,需考虑数据迁移或使用一致性哈希等策略。
五、常见排错清单
- 执行器显示离线:检查
appname是否与控制台完全一致;检查执行器与 Admin 的网络连通性。 - 任务未触发:检查 Cron 表达式是否正确;确认任务状态为“启动”。
- 分片不生效:确认路由策略选择了分片广播;代码中是否正确获取了
shardIndex和shardTotal。 - 日志报错 Token 无效:检查执行器配置的
accessToken是否与 Admin 控制台设置的一致。
