XXL-JOB 分布式定时任务框架:任务分片、失败重试、调度中心一次讲透

简介: 单机 @Scheduled 扛不住分布式定时任务?拆解 XXL-JOB 调度中心与执行器架构、任务分片、失败重试机制,附 30 分钟接入示例。

大家好,我是晚安code。

这篇就把 XXL-JOB 的调度、任务分片、失败重试讲透,看完你也能上手。

一、单机定时任务的三个坑

单机定时任务扛不住微服务,不是代码写得差,是架构上就没法横向扩展。(本文基于 XXL-JOB v2.4.x 常用用法,2026 年 8 月验证,官方最新已到 3.x)

用 Spring 自带的 @Scheduled 跑定时任务,图省事。等业务拆成微服务、实例从 1 台变 6 台,坑一个个冒出来:

1)重复执行:6 个实例各跑一遍,对账任务把同一批订单处理了 6 次。
2)没法横向扩展:10 万条数据单节点要跑 40 分钟,加机器也帮不上忙,因为任务只落在其中一台。
3)失败没人知道:半夜节点 OOM 了,任务静悄悄消失,第二天看数据才发现漏了一批。

单机定时任务,等于把可靠性赌在一台机器上

二、XXL-JOB 是什么:调度中心 + 执行器架构

XXL-JOB 把「什么时候执行」和「怎么执行」拆成两个独立角色,这是它能支撑集群扩缩容的根本。

XXL-JOB:许雪里开源的轻量级分布式任务调度平台(GitHub:https://github.com/xuxueli/xxl-job),把「什么时候执行」和「怎么执行」拆成两个角色。你可以理解为「给公司所有定时任务装一个统一指挥中心」。

调度中心(Scheduler Admin):XXL-JOB 的调度端,独立部署,提供 Web 界面管理任务、触发调度、失败重试和过期补偿,但不碰任何业务代码。你可以理解为「只负责发号施令的指挥部」。

执行器(Executor):打进业务服务里的一个 jar 包,负责接收调度、执行任务、回调结果,并自动向调度中心注册。你可以理解为「一线干活的执行部队」。

调度中心和执行器通过 HTTP 通信,互相不知道对方在哪台机器上——执行器启动后自己注册,调度中心按注册列表分发请求。所以执行器加一台、减一台,都不用改配置。

看图 1,整个链路就三条线:调度中心管任务、广播给执行器、执行器各自回调。

XXL-JOB 调度中心与执行器架构图:调度中心广播任务给多个执行器并回调

三、任务分片:10 万条数据怎么分给 N 台机器

任务分片广播是 XXL-JOB 处理海量数据并行最实用的一招,本质是「谁处理哪一份」由分片参数说了算。

任务分片广播:XXL-JOB 唯一会广播给所有执行器的路由策略,调度时把 shardIndex(当前分片序号)和 shardTotal(总分片数)一起发给每个执行器,大家按取模各处理一份数据。你可以理解为「一车货拆成 N 箱,每台车拉自己那一箱」。

比如 3 个执行器处理 10 万条用户数据:调度中心广播给全部 3 台,第 0 号处理 userId % 3 == 0 的数据,第 1 号处理 % 3 == 1 的,第 2 号处理 % 3 == 2 的,每台只跑三分之一,耗时直接砍到三分之一。新执行器上线,调度中心自动感知,下次调度 total 变成 4,数据自动重新切分,不用停机。

分片流程看图 2,注意每个执行器拿到的 index 不同。

XXL-JOB 任务分片广播流程:调度中心按 shardIndex 与 shardTotal 分发到各执行器

分片 Handler 的写法也不难,核心就两行取参:

// 每天 0 点,把海量用户数据分给所有在线执行器
@XxlJob("shardingUserDataHandler")
public void shardingUserData() {
   
    int index = XxlJobHelper.getShardIndex(); // 当前分片序号
    int total = XxlJobHelper.getShardTotal(); // 总分片数
    List<Long> userIds = queryUserIdsByShard(index, total);
    for (Long userId : userIds) {
   
        processUser(userId); // 只处理自己这一份
    }
}

分片广播 = 把 10 万条数据平均分给 N 个执行器,各干各的

四、失败重试与调度策略:不是加了 cron 就完事

分布式定时任务的可靠性,一半靠失败重试,另一半靠调度策略兜底。

阻塞处理策略:任务还没跑完、下一次调度又来了时怎么办的规则。XXL-JOB 默认「单机串行」,还有「丢弃后续调度」和「覆盖之前调度」两种可选。你可以理解为「排队窗口:要么排队,要么直接作废下一次」。

失败重试这一块,XXL-JOB 给了几个可配的旋钮:

1)失败重试次数:任务管理页可配,默认 0。核心业务我建议设 3。
2)失败重试间隔:默认 30 秒,支持指数退避,比如 "30,60,120" 表示三次重试分别等 30、60、120 秒。
3)代码主动标失败:业务里用 XxlJobHelper.handleFail() 标记失败,调度中心检测到失败且还有重试次数,就会自动再触发。

我看过太多事故,都是「重试次数设成 0」埋的雷。任务一挂,日志里一片红,第二天数据对不上才发现。

路由策略这边,XXL-JOB 提供轮询、随机、一致性哈希、故障转移、忙碌转移等。故障转移我常用:某台执行器挂了,调度自动转到下一台,业务几乎无感。还有调度过期补偿:错过了调度时间,可以选忽略或立即补触发,避免「该跑没跑」。

失败不可怕,可怕的是没有重试,也没有告警

可能有人会问:XXL-JOB 失败重试会不会把数据重复处理一遍?

会,如果任务不幂等。重试的代价就是可能重复执行,所以关键任务要么写幂等(比如按业务订单号去重),要么把重试次数控制住。我见过不幂等的对账任务被重试 3 次后账目乱了,排查了半天。

五、30 分钟接入实战

XXL-JOB 接入只要三步:加依赖、配置执行器、写 Handler,剩下交给调度中心界面。

1)加依赖,执行器核心就一个 jar:

<dependency>
    <groupId>com.xuxueli</groupId>
    <artifactId>xxl-job-core</artifactId>
    <version>2.4.1</version> <!-- 版本以官方最新为准,2.4.x 通用 -->
</dependency>

2)配执行器(application.yml):

xxl:
  job:
    admin:
      addresses: http://调度中心IP:8080/xxl-job-admin
    executor:
      appname: order-job        # 注册名,调度中心新增执行器时保持一致
      port: 9999                 # 执行器 HTTP 端口
      logpath: /data/applogs/xxl-job
    accessToken:                # 与调度中心一致的令牌,可为空

3)写 Handler,一个注解就是一类任务:

@Component
public class OrderJobHandler {
   
    // cron 方式:每天 0 点跑对账
    @XxlJob("orderReconcileJobHandler")
    public void reconcile() {
   
        // 你的业务逻辑
        XxlJobHelper.log("对账完成,共 {} 笔", count);
    }
}

然后在调度中心 Web 界面「新增任务」,执行器选 order-job,填 Cron 或固定间隔,保存即生效。整个链路从依赖到跑通,基本就是这几步。

可能有人会问:XXL-JOB 调度中心要不要也部署集群?

要,生产环境建议至少两个调度中心实例,用数据库锁保证同一时刻只有一个在调度,另一个故障时顶上。我这边就是双节点部署,出现过一次主节点宕机,任务没断,靠的就是这个。

六、XXL-JOB vs Quartz vs @Scheduled,怎么选

选型不是越重越好:任务少就用轻的,任务多、要分片、要重试,再上 XXL-JOB。

方案 分布式调度 任务分片 失败重试 适合规模
@Scheduled 不支持 个位数任务
Quartz 需自己改造 几十个任务
XXL-JOB 开箱即用 分片广播 次数+间隔 上百到上万个任务

项目里定时任务不超过 10 个、也不在意失败告警,@Scheduled 够用;一旦涉及多实例、海量数据、要分片,直接上 XXL-JOB,别自己造轮子。XXL-JOB 不是银弹,但在我这边,它是中小团队把分布式定时任务从「没人管」变成「平台管」的最轻方案,尤其是任务分片和失败重试这两块,省下的运维精力远超接入成本。

想深入可以看官方仓库和文档:


我是晚安code,持续分享编程干货。觉得有用的话记得点赞收藏和关注~也欢迎在评论区聊聊:你所在的项目用的是 XXL-JOB 还是别的定时任务框架,都踩过哪些坑?

目录
相关文章
|
2月前
|
算法 Java Nacos
Sentinel 流量治理实战:熔断降级限流 + Nacos 持久化
Sentinel 流量治理如何落地?本文从服务雪崩讲起,带你掌握熔断、降级、限流策略,配合 Nacos 实现规则持久化
401 0
|
1月前
|
人工智能 运维 自然语言处理
Geo专家于磊解析:GEO优化的基础、提升与突破
本文揭示生成式AI正重塑信息获取方式:用户不再点击链接,而是直接获取合成答案。GEO(生成式引擎优化)由此诞生——它不优化网页排名,而优化内容被AI采信、引用与复述的能力。Geo专家于磊提出“基础—提升—突破”三层框架,强调可信前提、可引用性、结构清晰是地基,数据支撑与答案岛是杠杆,实体网络与全域信任方达上限。
119 1
|
1月前
|
Java Shell API
专为 Managed Agents 而生的 Harness 底座:AgentScope 2.0
基于 AgentScope 2.0 的 Harness 内核与 Sandbox 隔离能力,AgentScope 可以作为 Managed Agents 的底层运行时 Runtime,为其提供稳定可靠的执行环境。
|
30天前
|
消息中间件 设计模式 算法
责任链模式是什么?适用场景 + 实战示例,告别 if-else 泥潭
责任链模式是什么?本文用请假审批的 Java 实战讲透责任链模式,手把手把 if-else 重构出责任链,并说清它的适用场景与坑。
87 1
责任链模式是什么?适用场景 + 实战示例,告别 if-else 泥潭
|
1月前
|
人工智能 定位技术 API
高德汽车业务 AI Native 工程实践|基于 Qoder 的业务知识工程建设实践
高德企业业务通过 Qoder 知识引擎构建业务知识的"生产—调优—更新—消费"体系,同一类错误不再发生第二次,任务一次性通过率从 37.3% 提升至 61.5%。
291 0
高德汽车业务 AI Native 工程实践|基于 Qoder 的业务知识工程建设实践
|
1月前
|
JSON 自然语言处理 Java
Elasticsearch查询实战:DSL与JavaRestClient一学就会
Elasticsearch查询离不开DSL语法和JavaRestClient:match、term、bool、分页、聚合一次讲透,看完就能写代码。
123 1
Elasticsearch查询实战:DSL与JavaRestClient一学就会
|
1月前
|
消息中间件 缓存 NoSQL
关注功能高并发怎么扛?Redis ZSet + Lua + MQ 异步落库一整套
关注功能高并发怎么设计?本文拆解 Redis ZSet 存关系、Lua 保原子性、MQ 异步落库、消费端令牌桶削峰四环,抗住瞬间洪峰。
101 1
|
11月前
|
人工智能 监控 Java
构建定时 Agent,基于 Spring AI Alibaba 实现自主运行的人机协同智能 Agent
借助 Spring AI Alibaba 框架,开发者可快速实现定制化自动定时运行的 Agent,构建数据采集、智能分析到人工参与决策的全流程AI业务应用。
2789 101
|
1月前
|
前端开发 数据挖掘 调度
阿里云通义千问的旗舰大模型qwen3.8-max介绍:核心能力、适用场景与最新优惠
本文介绍了阿里云通义千问系列最新旗舰Qwen3.8-Max大模型的核心能力与专属优惠。作为国内首个突破2.4万亿参数的原生多模态MoE架构模型,它支持百万级Token超长上下文,具备全栈代码工程能力与深度思考/极速响应双推理模式,可自主拆解复杂任务并调度多智能体协同执行,在专业办公自动化、科研数据分析等场景表现突出。当前该模型处于日更迭代的预览阶段,面向Token Plan订阅用户开放,叠加夜间22点至次日8点0.2折的错峰特惠,大幅降低了开发者与企业使用顶级旗舰模型的成本门槛。