Quartz vs XXL-Job vs ElasticJob 选型对比
三年前,你选择了 Quartz。
那时候项目小,三台服务器,单机调度够用。
现在项目大了,十台服务器,集群部署,Quartz 开始力不从心。
换哪个?XXL-Job 还是 ElasticJob?
今天,我们来彻底搞清楚这三个框架的区别。
先说结论
| 维度 | Quartz | XXL-Job | ElasticJob |
|---|---|---|---|
| 架构 | 单机 / 集群 | 调度中心 + 执行器 | 去中心化 / 云模式 |
| 管理界面 | 无(需二次开发) | 有(开箱即用) | 有(开箱即用) |
| 任务分片 | 不支持 | 支持 | 支持 |
| 故障转移 | 依赖数据库 | 执行器自抢 | ZooKeeper 选举 |
| 学习成本 | 中 | 低 | 中 |
| 适用场景 | 小型项目、快速集成 | 中大型项目 | 中大型项目、高可用 |
Quartz:老牌劲旅
核心特点
Quartz 是 Java 任务调度的「鼻祖」,2001 年发布,至今仍在广泛使用。
优点:
✅ 功能强大,Cron 表达式支持完善
✅ 与 Spring 无缝集成
✅ 集群模式基于数据库,稳定性高
✅ 社区活跃,文档丰富
缺点:
❌ 没有管理界面,需要自己开发
❌ 分布式调度需要额外配置(JDBC JobStore)
❌ 任务分片需要自己实现
❌ 调度和执行都在应用内,无法分离集群模式原理
Quartz 集群依赖数据库实现分布式协调:
sql
-- Quartz 集群使用数据库表(部分)
CREATE TABLE QRTZ_LOCKS (
LOCK_NAME VARCHAR(40) PRIMARY KEY
);
CREATE TABLE QRTZ_SCHEDULER_STATE (
INSTANCE_NAME VARCHAR(200) PRIMARY KEY,
LAST_CHECKIN_TIME BIGINT,
CHECKIN_INTERVAL BIGINT
);┌─────────────────────────────────────────────────────────────┐
│ Quartz 集群原理 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Node1 │ │ Node2 │ │ Node3 │ │
│ │ [调度器] │ │ [调度器] │ │ [调度器] │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │
│ └──────────────┼──────────────┘ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ 数据库 │ │
│ │ (分布式锁+状态) │ │
│ └─────────────────┘ │
│ │
│ 工作机制: │
│ 1. 多个节点竞争数据库锁 │
│ 2. 获得锁的节点负责调度 │
│ 3. 其他节点待命 │
│ 4. 调度节点宕机 → 其他节点抢锁接替 │
│ │
└─────────────────────────────────────────────────────────────┘适用场景
- 现有项目需要快速集成任务调度
- 团队没有专职运维,无法维护独立服务
- 任务量不大,不需要分片处理
XXL-Job:国产之光
核心特点
XXL-Job 是个人开发者(许雪里)开源的分布式任务调度平台,在国内拥有大量用户。
优点:
✅ 管理界面完善,开箱即用
✅ 任务分片、路由策略丰富
✅ GLUE 模式支持在线编辑代码
✅ 调度和执行分离,架构清晰
✅ 文档详细,中文友好
缺点:
❌ 调度中心需要独立部署
❌ 执行器注册依赖 MySQL
❌ 分片任务不支持动态分片数
❌ 社区主要在国内架构图
┌─────────────────────────────────────────────────────────────┐
│ XXL-Job 架构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 调度中心 │ │
│ │ (AdminSite - Web UI) │ │
│ │ │ │
│ │ · 任务管理 · 执行器注册 · 任务监控 · 日志 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ ┌──────────────┼──────────────┐ │
│ │ 触发执行 │ 执行结果回调 │ │
│ ▼ ▼ ▼ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ 执行器1 │ │ 执行器2 │ │ 执行器N │ │
│ │ (App Server)│ │ (App Server)│ │ (App Server)│ │
│ └────────────┘ └────────────┘ └────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ MySQL │ │
│ │ 任务配置 · 执行记录 · 执行器注册信息 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘路由策略
XXL-Job 支持多种路由策略,决定「把任务发给哪个执行器」:
| 策略 | 说明 | 适用场景 |
|---|---|---|
| FIRST | 第一个注册的执行器 | 测试环境 |
| LAST | 最后一个注册的执行器 | 特殊业务 |
| ROUND | 轮询 | 负载均衡 |
| RANDOM | 随机 | 负载均衡 |
| CONSISTENT_HASH | 一致性哈希 | 任务与执行器绑定 |
| LEAST_LOADED | 最少负载 | 动态负载均衡 |
| FAILOVER | 失败自动切换 | 容错处理 |
| BUSY_OVER | 繁忙节点跳过 | 防止单节点过载 |
适用场景
- 需要可视化管理界面
- 团队有运维能力维护调度中心
- 需要 GLUE 模式在线开发任务
- 中大型分布式系统
ElasticJob:分片利器
核心特点
ElasticJob 是当当网开源的分布式调度框架,最初基于 Quartz,现在已经完全重写。
优点:
✅ 支持任务分片(核心亮点)
✅ 无中心化设计,ZooKeeper 协调
✅ Lite 和 Cloud 两种部署模式
✅ 多种作业类型(Simple、Dataflow、Script)
✅ 事件追踪、作业监听器完善
缺点:
❌ 需要 ZooKeeper(运维成本)
❌ 学习曲线较陡
❌ 分片逻辑需要自己实现
❌ Cloud 模式已停止维护架构图
┌─────────────────────────────────────────────────────────────┐
│ ElasticJob-Lite 架构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ AppServer1 │ │ AppServer2 │ │ AppServer3 │ │
│ │ ┌────────┐ │ │ ┌────────┐ │ │ ┌────────┐ │ │
│ │ │ 作业调度 │ │ │ │ 作业调度 │ │ │ │ 作业调度 │ │ │
│ │ │ + 执行 │ │ │ │ + 执行 │ │ │ │ + 执行 │ │ │
│ │ └────────┘ │ │ └────────┘ │ │ └────────┘ │ │
│ └──────┬─────┘ └──────┬─────┘ └──────┬─────┘ │
│ │ │ │ │
│ └───────────────┼───────────────┘ │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ ZooKeeper │ │
│ │ · 主节点选举 │ │
│ │ · 分片分配 │ │
│ │ · 故障检测 │ │
│ └─────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘分片原理
ElasticJob 的分片是它的核心能力:
java
public class MyShardingJob implements SimpleJob {
@Override
public void execute(ShardingContext context) {
// 获取当前节点负责的分片
ShardingVO sharding = context.getSharding();
switch (sharding.getShardingItem()) {
case 0:
// 分片0:处理用户数据
processUsers(sharding);
break;
case 1:
// 分片1:处理订单数据
processOrders(sharding);
break;
case 2:
// 分片2:处理商品数据
processProducts(sharding);
break;
}
}
}适用场景
- 需要任务分片处理大数据量
- 已有 ZooKeeper 集群
- 对高可用要求较高
- 需要灵活的分片策略
横向对比
功能对比
| 功能 | Quartz | XXL-Job | ElasticJob |
|---|---|---|---|
| 管理界面 | ❌ | ✅ | ✅ |
| 任务分片 | ❌ | ✅ | ✅ |
| 失败重试 | ❌ | ✅ | ✅ |
| 任务依赖 | ❌ | ✅ | ❌ |
| 任务超时 | ❌ | ✅ | ✅ |
| 阻塞处理 | ❌ | ✅ | ✅ |
| 事件追踪 | ❌ | ✅ | ✅ |
| 告警通知 | ❌ | ✅ | ✅ |
| 动态配置 | ❌ | ✅ | ❌ |
| GLUE 代码 | ❌ | ✅ | ❌ |
运维对比
| 维度 | Quartz | XXL-Job | ElasticJob |
|---|---|---|---|
| 依赖服务 | MySQL | MySQL + 调度中心 | ZooKeeper |
| 部署复杂度 | 低 | 中 | 中 |
| 运维难度 | 低 | 中 | 高 |
| 水平扩展 | 难 | 易 | 易 |
| 故障恢复 | 自动 | 自动 | 自动 |
性能对比
假设场景:1000 个任务,每分钟执行一次
Quartz(集群模式):
- 调度中心:每分钟触发 1000 次
- 执行节点:竞争锁后执行
- 瓶颈:数据库锁竞争
XXL-Job:
- 调度中心:每分钟触发 1000 次
- 执行器:接收调度指令后执行
- 瓶颈:调度中心单点(可通过集群解决)
ElasticJob:
- 无中心调度:各节点竞争 ZooKeeper 锁
- 瓶颈:ZooKeeper 集群性能选型决策树
开始选择
│
▼
需要管理界面?
│
├── 否 ──▶ Quartz(自己开发 or 二次开发)
│
└── 是 ──▶ 有 ZooKeeper 集群?
│
├── 否 ──▶ XXL-Job
│
└── 是 ──▶ 需要任务分片?
│
├── 否 ──▶ XXL-Job
│
└── 是 ──▶ 任务分片复杂度?
│
├── 简单分片 ──▶ XXL-Job
│
└── 复杂分片 ──▶ ElasticJob总结
| 框架 | 核心优势 | 最大劣势 | 最佳拍档 |
|---|---|---|---|
| Quartz | 功能完整、集成简单 | 无管理界面 | Spring Boot |
| XXL-Job | 开箱即用、GLUE 模式 | 需要运维调度中心 | 微服务架构 |
| ElasticJob | 强大分片、去中心化 | 需要 ZooKeeper | 大数据处理 |
我的建议:
- 小型项目(< 5 个服务):先用 Quartz,不够再说
- 中型项目(5-20 个服务):XXL-Job,上手快,功能全
- 大型项目 / 大数据场景:ElasticJob,分片能力强
思考题
如果让你设计一个任务调度系统,你会选择调度中心模式还是去中心化模式?
各自的优缺点是什么?有没有第三种方案?
这个问题没有标准答案,值得深入思考。
