
XXL-JOB 是一个轻量级分布式任务调度平台,核心设计是调度中心(Admin) 与执行器(Executor) 分离:调度中心负责任务的管理和触发,执行器负责接收调度请求并执行业务代码。下面从零开始,一步步说明如何使用 v2.5.0。
从官方仓库下载源码:
# GitHubgit clone https://github.com/xuxueli/xxl-job.git# 或 Gitee(国内更快)git clone https://gitee.com/xuxueli0323/xxl-job.git
项目结构说明:
xxl-job-admin:调度中心(需要部署)xxl-job-core:公共核心依赖(执行器引入)xxl-job-executor-samples:执行器示例代码doc/db/tables_xxl_job.sql:数据库初始化脚本执行 doc/db/tables_xxl_job.sql 脚本,会生成 8 张表:
| 表名 | 用途 |
|---|---|
xxl_job_lock | 任务调度锁表(分布式调度协调) |
xxl_job_group | 执行器信息表 |
xxl_job_info | 任务扩展信息表 |
xxl_job_log | 调度日志表 |
xxl_job_log_report | 调度日志报表 |
xxl_job_logglue | GLUE 模式日志(版本回溯) |
xxl_job_registry | 执行器注册表 |
xxl_job_user | 系统用户表 |
编辑 xxl-job-admin/src/main/resources/application.properties,必须修改以下配置:
# 1. 数据库连接(必须修改)spring.datasource.url=jdbc:mysql://your-host:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai&useSSL=falsespring.datasource.username=your-usernamespring.datasource.password=your-passwordspring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver# 2. AccessToken(生产环境必须修改为复杂随机字符串)xxl.job.accessToken=your-production-token# 3. 可选:日志保留天数xxl.job.logretentiondays=30# 4. 可选:线程池大小xxl.job.triggerpool.fast.max=200xxl.job.triggerpool.slow.max=100
直接运行 XxlJobAdminApplication 类的 main 方法。
访问 http://localhost:8080/xxl-job-admin,默认用户名/密码:admin/123456。
登录后,可以看到以下功能模块:
在业务项目的 pom.xml 中添加:
<dependency> <groupId>com.xuxueli</groupId> <artifactId>xxl-job-core</artifactId> <version>2.5.0</version></dependency>
在 application.yml 或 application.properties 中配置:
# 调度中心地址(集群用逗号分隔多个)xxl.job.admin.addresses=http://localhost:8080/xxl-job-admin# 执行器名称(唯一标识)xxl.job.executor.appname=xxl-job-executor-demo# 执行器端口(默认9999,生产建议修改)xxl.job.executor.port=9999# AccessToken(必须与调度中心一致)xxl.job.accessToken=your-production-token# 日志路径xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler# 日志保留天数xxl.job.executor.logretentiondays=30
创建配置类,初始化 XxlJobSpringExecutor:
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class XxlJobConfig { private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class); @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.accessToken}") private String accessToken; @Value("${xxl.job.executor.logpath}") private String logPath; @Value("${xxl.job.executor.logretentiondays}") private int logRetentionDays; @Bean public XxlJobSpringExecutor xxlJobExecutor() { logger.info(">>>>>>>>>>> xxl-job config init."); XxlJobSpringExecutor executor = new XxlJobSpringExecutor(); executor.setAdminAddresses(adminAddresses); executor.setAppname(appname); executor.setPort(port); executor.setAccessToken(accessToken); executor.setLogPath(logPath); executor.setLogRetentionDays(logRetentionDays); return executor; }}启动业务应用后,执行器会自动向调度中心注册。登录调度中心后台,在执行器管理页面应该能看到注册上来的执行器信息。
生产环境强烈推荐使用 BEAN 模式,而不是 GLUE 模式。BEAN 模式的代码在业务项目中,可以进行版本控制和 Code Review,更加安全可控。
import com.xxl.job.core.context.XxlJobHelper;import com.xxl.job.core.handler.annotation.XxlJob;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Component;@Componentpublic class SampleXxlJob { private static Logger logger = LoggerFactory.getLogger(SampleXxlJob.class); /** * 简单任务示例 * 注解中的 "demoJobHandler" 是任务标识,在调度中心配置时需要用到 */ @XxlJob("demoJobHandler") public void demoJobHandler() throws Exception { XxlJobHelper.log("XXL-JOB, Hello World."); // 获取任务参数(在调度中心配置时填写) String jobParam = XxlJobHelper.getJobParam(); XxlJobHelper.log("任务参数: {}", jobParam); for (int i = 0; i < 5; i++) { XxlJobHelper.log("beat at: {}", i); Thread.sleep(2000); } // 默认返回 SUCCESS }}当执行器集群部署时,使用分片广播路由策略可以让每个节点处理一部分数据,提高处理效率。
import com.xxl.job.core.context.XxlJobHelper;import com.xxl.job.core.handler.annotation.XxlJob;import org.springframework.stereotype.Component;@Componentpublic class ShardingJob { @XxlJob("shardingJobHandler") public void shardingJobHandler() throws Exception { // 获取分片参数 int shardIndex = XxlJobHelper.getShardIndex(); // 当前分片序号(从0开始) int shardTotal = XxlJobHelper.getShardTotal(); // 总分片数 XxlJobHelper.log("分片参数:当前分片序号 = {}, 总分片数 = {}", shardIndex, shardTotal); // 业务逻辑:根据分片参数查询数据 // 例如:从数据库查询 order_id % shardTotal == shardIndex 的数据 // 每个节点只处理自己分片的数据,避免重复处理 for (int i = 0; i < shardTotal; i++) { if (i == shardIndex) { XxlJobHelper.log("第 {} 片,命中分片开始处理", i); // 执行具体业务逻辑... } else { XxlJobHelper.log("第 {} 片,忽略", i); } } }}分片广播适用场景:海量数据处理、日志分析、订单批量处理等需要并行提升效率的场景。
登录调度中心后台,进入任务管理页面,点击新增。
| 配置项 | 说明 | 示例 |
|---|---|---|
| 执行器 | 选择注册上来的执行器 | xxl-job-executor-demo |
| 任务描述 | 任务名称 | 测试任务 |
| 负责人 | 任务负责人 | admin |
| 调度类型 | CRON / 固定速度 | CRON |
| Cron 表达式 | 定时调度规则 | 0/10 * * * * ?(每10秒执行一次) |
Cron 表达式常用示例:
0 0 0 * * ?:每天0点触发0 30 10 * * ?:每天10点30分触发0 0/5 * * * ?:每5分钟触发0 0/10 * * * ?:每10分钟触发| 配置项 | 说明 |
|---|---|
| 运行模式 | 选择 BEAN 模式(生产推荐) |
| JobHandler | 填写 @XxlJob 注解中的名称,如 demoJobHandler |
| 任务参数 | 执行时传入的参数,代码中通过 XxlJobHelper.getJobParam() 获取 |
| 路由策略 | 见下文路由策略说明 |
| 阻塞处理策略 | 调度超时或任务执行过慢时的处理方式 |
执行器集群部署时,需要选择路由策略决定任务由哪个节点执行:
| 路由策略 | 说明 | 适用场景 |
|---|---|---|
| FIRST | 固定选择第一个执行器 | 不推荐生产使用 |
| LAST | 固定选择最后一个执行器 | 不推荐生产使用 |
| ROUND | 轮询选择在线执行器 | 无状态任务,负载均衡 |
| RANDOM | 随机选择在线执行器 | 无状态任务 |
| CONSISTENT_HASH | 一致性 HASH,同一任务固定同一台机器 | 有状态任务(需缓存本地数据) |
| FAILOVER | 故障转移,按顺序心跳检测,第一个成功的执行 | 关键任务,高可用 |
| BUSYOVER | 忙碌转移,按顺序空闲检测,第一个空闲的执行 | 高负载场景 |
| SHARDING_BROADCAST | 分片广播,所有执行器执行,传递分片参数 | 海量数据并行处理 |
在任务管理页面,点击任务的操作列,选择执行一次。在弹出的对话框可以填写执行参数,也可以指定某台 IP 执行(方便 Debug)。
执行完成后,点击查看日志可以查看调度记录和任务执行日志。日志会显示:
XxlJobHelper.log() 输出的业务日志| 检查项 | 说明 |
|---|---|
| AccessToken 已配置且非默认值 | 生产必须修改 |
| 调度中心与执行器 Token 一致 | 否则注册失败 |
| 数据库连接信息已修改 | 使用生产数据库 |
| 执行器端口非默认 9999 | 避免冲突 |
| 使用 BEAN 模式而非 GLUE 模式 | 安全可控 |
| 路由策略已按业务需求选择 | 集群环境必须考虑 |
| 阻塞处理策略已配置 | 防止任务堆积 |