跳到正文

设计取舍与对比 ​

一句话:XXL-JOB 的极简主义是「用已有的 MySQL 同时当配置库、注册表和分布式锁,用 HTTP 当 RPC」;它换来了部署和排障的简单,代价是中心化、秒级上限和 DB 依赖。

适用版本:XXL-JOB 2.3.x / 2.4.0;对比对象为 ElasticJob 3.x、阿里云 SchedulerX。版本不同结论可能变化。

为什么需要 ​

选调度框架时,真正要回答的不是「谁功能多」,而是「我的团队能维护什么」。引入 ZooKeeper 能换来自动分片和去中心化,但也多了一套必须有人值守的集群;引入云托管能省掉运维,但换来账单和厂商绑定。

XXL-JOB 的每个设计决策,都是在这条「运维成本 vs 能力」的线上选了偏左的位置。

核心机制 ​

取舍一:中心化还是去中心化 ​

XXL-JOB 把决策集中在 Admin:任务配置、路由、触发、日志、告警都在一个 Web 控制台里。好处是排障路径短——「为什么没跑」通常能在 Admin 的调度日志里看到;坏处是 Admin 和 DB 成为中心,Admin 全挂时新任务不再触发。

ElasticJob 走另一条路:每个实例平等,靠 ZooKeeper 协调,分片和再均衡由框架完成。它没有中心调度器,弹性更好;代价是状态分散在 ZK 和各实例日志里,排障要同时看两边。

这不是「谁更先进」,而是「你愿意把复杂度放在哪」:XXL-JOB 放在 Admin + DB,ElasticJob 放在 ZK + 客户端。

取舍二:HTTP 还是 RPC ​

XXL-JOB 用 HTTP + JSON,理由不是性能,而是接入和排障成本:

  • 任何语言都能发 HTTP,写非 Java 执行器不需要生成 proto;
  • curl 就能验证 /run、/beat;
  • Admin 和 Executor 都是 Web 服务,不需要额外的 RPC 框架。

代价是没有连接池、没有多路复用、没有服务端流;一次 /run 是一次短连接请求。调度 QPS 不高时这不算问题,高频短任务就不合适。

取舍三:扫表 + 时间环,还是 Quartz / 纯时间轮 ​

Quartz 自带 JobStore、集群锁和 misfire 机制,能力完整,但接入一个调度平台还要理解它的表结构和集群规则。XXL-JOB 只复用了 Quartz 的 CronExpression 做表达式解析,触发则自己实现:

  • xxl_job_info.trigger_next_time 是持久化的「下次时间」;
  • 调度线程每轮预读未来 5 秒,把临近的 jobId 放进 60 槽秒级时间环;
  • 多 Admin 用 xxl_job_lock 行锁串行认领。

纯时间轮(如 Netty HashedWheelTimer)适合海量短延时任务,但它是内存结构,进程重启就丢;XXL-JOB 的场景是分钟级到天级的 cron,持久化和 HA 比 O(1) 插入更重要。代价是秒级精度、扫表开销和 DB 依赖。

取舍四:MySQL 还是 ZooKeeper 做协调 ​

XXL-JOB 用 MySQL 行锁做多 Admin 互斥,用一张注册表做服务发现。好处是复用已有组件:大多数团队本来就有 MySQL 高可用,不需要再维护 ZK。

代价是:

  • 没有 Watch,注册变化靠 30 秒轮询;
  • DB 是单点,DB 挂了两者都不可用;
  • 行锁粒度粗,一轮扫表事务持有锁,DB 慢查询会拖住其他 Admin。

ZK 的强一致和实时通知更强,但也更重。XXL-JOB 选的是「够用」。

取舍五:GLUE 还是 BEAN ​

GLUE 把代码存在 xxl_job_info.glue_source,历史版本在 xxl_job_logglue,可以在 Admin 页面在线编辑、发布,不用重启 Executor。适合临时脚本、排障脚本。

代价是代码脱离 Git 和 CI,依赖、版本、回滚都靠平台;复杂业务写 GLUE 会很难维护。生产主线任务用 BEAN:代码在仓库里,走正常发布流程;GLUE 只作为补充。

和 ElasticJob 的一段对比 ​

ElasticJob 3.x 的核心是「去中心化 + 自动分片」:实例通过 ZooKeeper 协调,任务分片数在配置里显式指定,实例增减时自动再均衡。它适合已经有 ZK 运维能力、任务需要弹性伸缩的团队。

XXL-JOB 的分片数等于注册实例数,扩容后数据切分规则会变,但没有自动再均衡和断点迁移;它更适合任务量中等、希望有一个统一控制台和日志入口的团队。两者都能跑 cron,但分片语义和运维模型不同,不能按「功能表」直接互换。

和 SchedulerX 的一段对比 ​

SchedulerX 是阿里云托管的产品:不需要自己部署 Admin 和 DB,提供秒级调度、MapReduce、工作流和监控告警。适合不想管基础设施、任务规模较大、预算允许的团队。

代价是厂商绑定和持续费用;离线环境、强数据合规场景通常不会选它。XXL-JOB 则完全自托管,数据留在自己的 MySQL 里。

最小上手 ​

同一个「每 30 秒执行、两个分片」的任务,两边的配置差异如下。

XXL-JOB:代码里只声明 Handler,cron 和路由在 Admin 页面/DB 里配,分片总数由注册实例数决定。

java
@XxlJob("demoJobHandler")
public void demoJobHandler() {
    int index = XxlJobHelper.getShardIndex();
    int total = XxlJobHelper.getShardTotal();
    XxlJobHelper.log("shard={}/{}", index, total);
}

ElasticJob 3.x:分片总数显式写在配置里,任务类实现 SimpleJob,协调依赖 ZooKeeper。

yaml
# ElasticJob 3.x;键名以官方文档为准
elasticjob:
  reg-center:
    server-lists: 127.0.0.1:2181
    namespace: demo
  jobs:
    demoJob:
      elastic-job-class: com.example.DemoJob
      cron: "0/30 * * * * ?"
      sharding-total-count: 2
java
public class DemoJob implements SimpleJob {
    @Override
    public void execute(ShardingContext ctx) {
        int index = ctx.getShardingItem();
        int total = ctx.getShardingTotalCount();
    }
}

差异不在代码量,而在「分片数是谁的职责」:XXL-JOB 把它交给注册实例数,ElasticJob 把它作为任务配置。

生产动作 ​

选型时按顺序问四个问题:

问题倾向
已经有可运维的 ZooKeeper,且需要实例增减自动再分片?ElasticJob
任务量中等(几十到几百),想要统一控制台、日志和告警?XXL-JOB
不想自建 Admin/DB,需要托管和工作流?SchedulerX
需要亚秒级、海量短延时或流式处理?都不是,换消息队列/流处理

成本核算:

  • XXL-JOB:Admin 至少 2 实例 + MySQL 高可用;Executor 无状态。主要风险是 Admin 与 DB。
  • ElasticJob:ZK 集群 + 各实例;主要风险是 ZK 的运维和会话。
  • SchedulerX:托管费 + 网络出口;主要风险是厂商绑定。

迁移注意:cron 都是 Quartz 风格,表达式通常能直接复用;但分片语义不同(实例数 vs 显式分片数),数据切分、幂等、补跑逻辑要重新验证,不能只改配置就上线。

不要用社区热度做决策:Star 数、文章数量都会随时间变化,和你的运维能力、任务模型没有关系。把「谁能在凌晨排障」作为第一优先级。

边界 ​

  • XXL-JOB 不适合:亚秒级高频调度、海量短延时任务、复杂 DAG 工作流、要求 Exactly-Once 的业务。
  • ElasticJob 不适合:没有 ZK 运维能力、只需要简单 cron 的团队;为了自动分片引入一套 ZK 通常不划算。
  • SchedulerX 不适合:离线/专有云、强数据合规、预算敏感的场景。
  • GLUE 不适合:有复杂依赖、需要代码评审和 CI 的主线业务;它适合脚本型任务。
  • 对比表会过期:功能、版本、默认值都在变,选型前以对应版本文档为准,不要照搬旧文。

讲清楚 ​

XXL-JOB 的设计哲学是「把复杂度放在已有的组件上」。它用 MySQL 同时做配置库、注册表和行锁,用 HTTP 做调度和回调,用扫表 + 秒级时间环代替 Quartz 集群。好处是部署只需要一个数据库,排障只需要看 Admin 和日志;代价是中心化、DB 依赖、秒级精度,以及分片数被注册实例数绑死。ElasticJob 把复杂度放在 ZooKeeper 和客户端,换来去中心化和自动再分片;SchedulerX 把复杂度交给云厂商,换来免运维和厂商绑定。选型不是比功能表,而是问:我的团队能维护什么、任务量多大、能不能接受中心化。任务量中等、想要统一控制台,选 XXL-JOB;已有 ZK、需要弹性分片,选 ElasticJob;不想管基础设施且预算允许,选 SchedulerX;亚秒级或流式,三者都不合适。

适用 XXL-JOB 2.3.x / 2.4.0 | 初稿 2026-10

把一门技术讲透到既懂也会用