← 返回题目列表

XXL-JOB 有哪些路由策略?分片广播是怎么回事?

高频 中等 第 12 / 25 题 更新于 2026/07/28
任务调度XXL-JOB路由策略分片广播

简化版

当一个任务的执行器有多个实例时,调度中心需要一个路由策略决定「把这次调度发给哪个实例」。XXL-JOB 常见路由策略:第一个、最后一个、轮询、随机、一致性哈希、最不经常使用、最近最久未使用、故障转移(选一个健康的)、忙碌转移、分片广播。其中最特别、最重要的是分片广播(Sharding Broadcast)——它同时调度所有执行器实例,并给每个实例分配一个分片编号(shardIndex)和总分片数(shardTotal),每个实例根据自己的分片号只处理属于自己那一部分的数据,实现一个大任务拆分到多台机器并行处理。这是 XXL-JOB 处理大数据量任务的杀手锏。

详细版

常见路由策略:

策略说明
第一个 / 最后一个固定选列表第一个/最后一个实例
轮询 / 随机依次轮流 / 随机选一个实例
一致性哈希按任务哈希固定到某实例(粘性)
最不经常使用 LFU / 最近最久未使用 LRU按使用频率/时间选
故障转移(Failover)逐个心跳检测,选第一个健康的实例
忙碌转移(Busyover)逐个检测,选第一个空闲的实例
分片广播(Sharding Broadcast)同时调度所有实例,每个处理一个分片

分片广播的核心:

@XxlJob("shardingJob")
public void shardingJob() {
    int shardIndex = XxlJobHelper.getShardIndex();   // 当前实例的分片号 (0,1,2...)
    int shardTotal = XxlJobHelper.getShardTotal();   // 总分片数 (=实例数)
    // 每个实例只处理 id % shardTotal == shardIndex 的数据
    List<Data> myData = queryByShard(shardIndex, shardTotal);
    process(myData);
}

完整版教学

一、路由策略要解决什么

XXL-JOB 里,一个任务对应的执行器通常部署了多个实例(业务应用集群)。当任务到了触发时间,调度中心要发起调度——发给哪个实例执行? 这就是路由策略要决定的。不同策略适合不同需求:有的固定选一个、有的轮流、有的挑健康的、有的全都调度(分片广播)。选对路由策略,能实现负载均衡、故障转移、或并行分片处理。

二、普通路由策略(选一个实例执行)

大部分路由策略是从多个实例里选一个来执行任务:

  • 第一个 / 最后一个:固定选执行器列表里的第一个 / 最后一个实例。简单固定。
  • 轮询(Round Robin):依次轮流选实例,任务均匀分散到各实例。
  • 随机(Random):随机选一个实例。
  • 一致性哈希:按任务 ID 哈希,同一个任务固定路由到同一个实例(粘性),适合有状态/缓存亲和。
  • LFU(最不经常使用)/ LRU(最近最久未使用):按实例被使用的频率/时间来选,做负载均衡。
  • 故障转移(Failover)逐个对实例做心跳检测,选第一个心跳正常(健康)的实例执行。保证任务发给活着的实例,实现高可用。
  • 忙碌转移(Busyover):逐个检测实例是否空闲,选第一个空闲的(当前没在跑任务的)实例执行,避免发给正忙的实例。

这些策略的共同点是:一次调度只有一个实例执行任务(其他实例不参与这次任务)。

三、分片广播:一个任务拆到多机并行(重点)

分片广播(Sharding Broadcast) 是最特殊、最重要的路由策略,它和上面的完全不同——它会同时调度该任务的所有执行器实例,让它们一起参与、各自处理一部分数据,实现并行分片处理

核心机制:调度中心广播任务给所有实例时,给每个实例分配两个参数

  • shardIndex(分片序号):当前实例是第几个分片(从 0 开始:0, 1, 2, …)。
  • shardTotal(分片总数):总共有几个分片(= 执行器实例数)。

每个实例在 JobHandler 里拿到自己的 shardIndexshardTotal,然后只处理「属于自己分片」的那部分数据。最常见的分片方式是按数据 ID 取模

  • 3 个实例,shardTotal=3,各自 shardIndex 是 0、1、2。
  • 实例 0 处理 id % 3 == 0 的数据,实例 1 处理 id % 3 == 1,实例 2 处理 id % 3 == 2
  • 这样 1000 万条数据被均匀拆成 3 份,3 台机器并行处理,速度提升约 3 倍,且没有重复(每条数据只被一个分片处理)。

四、分片广播的价值:处理海量数据

分片广播解决了「单机处理不了的大数据量任务」——比如「给 1000 万用户发账单」「清理上亿条历史数据」。

  • 单机跑:一台机器处理 1000 万条,又慢又可能撑不住。
  • 分片广播:任务拆分到集群 N 台机器并行处理,每台只处理 1/N,速度提升 N 倍,充分利用集群算力。

而且分片是动态的——如果执行器实例数变了(扩容/缩容),shardTotal 会自动变化,分片自动重新分配,弹性伸缩。这是 XXL-JOB 相比 Quartz 集群(不支持单任务分片)的重要优势。

五、使用分片广播的注意点

  • 数据分片要均匀:按 ID 取模是常用且均匀的方式;要保证数据能被 shardTotal 均匀切分,避免某个分片数据特别多导致倾斜。
  • 分片逻辑在业务代码里:XXL-JOB 只负责把 shardIndex/shardTotal 传给每个实例,具体怎么根据分片号筛选数据、是你的 JobHandler 代码要实现的(如 SQL 里加 where id % shardTotal = shardIndex)。
  • 无状态、可并行:分片的各部分数据处理要相互独立、可并行,不能有跨分片的依赖。
  • 失败处理:某个分片实例执行失败,可配合失败重试;要考虑重试时的幂等。

六、常见误区与追问

这道题面试时最容易丢分的地方,是把「XXL-JOB 路由与分片」答成一段泛泛的组件介绍。更稳的答法是先给结论,再沿着 分布式任务调度链路 拆清楚流程,最后补上异常场景、数字边界和选型取舍。

回答层次要讲清的内容容易漏掉的边界
核心定义路由决定任务发给哪个执行器,分片广播让多个执行器各自处理不同数据范围不要停在名词解释
流程机制调度中心获取执行器列表 -> 按路由策略选择节点 -> 分片广播时通知所有节点 -> 每个节点拿到 shardIndex/shardTotal -> 按分片处理数据 -> 分别回报结果说明谁触发、谁存储、谁通知、谁兜底
工程取舍3 个执行器分片时 shardTotal=3,shardIndex 分别为 0、1、2,可按 userId % 3 分配数据调度系统解决统一触发和治理,业务侧仍要保证幂等,因为网络抖动和重试不可避免
XXL-JOB 路由与分片 面试拆解:
1. 调度中心获取执行器列表
2. 按路由策略选择节点
3. 分片广播时通知所有节点
4. 每个节点拿到 shardIndex/shardTotal
5. 按分片处理数据
6. 分别回报结果

记忆钩子:先区分调度中心、执行器、触发、路由、分片、重试和告警,再说明如何避免重复执行;回答时一定要落到题目中的「XXL-JOB 路由与分片」,不要把相邻中间件的能力混着讲。

  • 误区:路由和分片是一回事。 路由是选择执行器,分片是把一个大任务拆给多个执行器并行处理。
  • 误区:分片广播会自动拆数据。 框架传 shardIndex 和 shardTotal,具体数据范围要业务代码自己计算。
  • 误区:分片越多越快。 分片过多会增加调度、连接和下游压力,瓶颈可能转移到数据库。
  • 追问:常见路由策略有哪些? 第一个、最后一个、轮询、随机、一致性哈希、最不经常使用、分片广播等。
  • 追问:如何保证分片不重复不遗漏? 使用稳定的取模、范围切分或游标规则,并记录处理进度。
  • 追问:某个分片失败怎么办? 只重试失败分片或补偿对应数据范围,业务侧要保证幂等。

七、加强记忆

XXL-JOB 路由策略决定「任务的多个执行器实例中,这次调度发给谁」。普通策略(选一个实例):第一个/最后一个、轮询、随机、一致性哈希(粘性)、LFU/LRU、故障转移(选第一个健康实例)、忙碌转移(选第一个空闲实例)。最重要的是分片广播(Sharding Broadcast)——同时调度所有实例,给每个实例分配 shardIndex(分片号 0,1,2…)+ shardTotal(总分片数=实例数),每个实例只处理属于自己分片的数据(常按 id % shardTotal == shardIndex 取模),实现一个大任务拆到多机并行处理(1000 万数据拆 N 份、N 台并行、提速 N 倍、无重复)。价值:处理单机搞不定的海量数据 + 弹性伸缩(实例变则分片自动重分)。注意:分片均匀、分片筛选逻辑在业务代码里写、各分片独立可并行。口诀:普通策略选一个执行、分片广播全体并行各处理一片(shardIndex/shardTotal 取模分数据)