Skip to content

ElasticJob 架构

XXL-Job 是调度中心模式,所有调度都在一个独立的「大脑」中进行。

但如果你的业务服务器已经是一个集群,还要额外维护一个调度中心集群,是不是有点麻烦?

ElasticJob 提供了另一种选择——去中心化的架构。

每个业务服务器都内置调度能力,通过 ZooKeeper 协调,谁抢到任务谁执行。

什么是 ElasticJob?

ElasticJob 是当当网开源的分布式调度框架,目前有两个主要版本:

┌─────────────────────────────────────────────────────────────┐
│                    ElasticJob 版本                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   ElasticJob 2.x(已停止维护)                               │
│   ├── 基于 Quartz                                           │
│   └── 使用 ZooKeeper 协调                                   │
│                                                             │
│   ElasticJob 3.x(当前版本)                                │
│   ├── 完全重写                                              │
│   ├── 移除 Quartz 依赖                                      │
│   ├── 支持 Lite 和 Cloud 两种模式                           │
│   └── 性能大幅提升                                          │
│                                                             │
└─────────────────────────────────────────────────────────────┘

两种部署模式

┌─────────────────────────────────────────────────────────────┐
│                    ElasticJob 两种模式                        │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   ┌───────────────────────┐  ┌───────────────────────┐      │
│   │      LiteJob         │  │       CloudJob        │      │
│   │     (轻量级)         │  │      (云原生)        │      │
│   └───────────────────────┘  └───────────────────────┘      │
│            │                            │                    │
│            ▼                            ▼                    │
│   ┌───────────────────────┐  ┌───────────────────────┐      │
│   │ · 无中心化设计         │  │ · 需要 Mesos 集群     │      │
│   │ · 嵌入业务应用         │  │ · 常驻进程运行        │      │
│   │ · ZooKeeper 协调     │  │ · 资源动态分配        │      │
│   │ · 运维简单            │  │ · 运维复杂            │      │
│   └───────────────────────┘  └───────────────────────┘      │
│                                                             │
└─────────────────────────────────────────────────────────────┘

LiteJob:轻量级

LiteJob 将调度框架嵌入到业务应用,每个应用实例都是一个「调度节点」:

xml
<dependency>
    <groupId>org.apache.shardingsphere.elasticjob</groupId>
    <artifactId>elasticjob-lite-core</artifactId>
    <version>3.0.4</version>
</dependency>
java
@SpringBootApplication
public class MyApplication {
    
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

@Configuration
public class ElasticJobConfig {
    
    @Bean
    public CoordinatorRegistryCenter registryCenter() {
        return new ZookeeperRegistryCenter(
            new ZookeeperConfiguration("localhost:2181", "elastic-job")
        );
    }
    
    @Bean
    public JobScheduler jobScheduler(CoordinatorRegistryCenter registryCenter) {
        return new SpringJobScheduler(
            new MyJob(),
            registryCenter,
            getJobConfiguration()
        );
    }
}

CloudJob:云原生

CloudJob 需要配合 Mesos 使用,适合需要精细化资源管理的场景:

┌─────────────────────────────────────────────────────────────┐
│                    CloudJob 架构                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   ┌─────────────┐  ┌─────────────┐  ┌─────────────┐      │
│   │   Mesos     │  │   Mesos     │  │   Mesos     │      │
│   │  Master     │  │   Agent1    │  │   Agent2    │      │
│   └─────────────┘  └─────────────┘  └─────────────┘      │
│          │                                    │              │
│          │              ┌────────────────────┘              │
│          │              ▼                                    │
│          │       ┌─────────────┐                           │
│          │       │  ElasticJob │                           │
│          │       │   Cloud    │                           │
│          │       │   Executor │                           │
│          │       └─────────────┘                           │
│          │                                                   │
│          │       ┌─────────────┐                           │
│          │       │ Job Server  │ ← 作业服务器(无状态)      │
│          │       └─────────────┘                           │
│          │                                                   │
└──────────┴───────────────────────────────────────────────────┘

注意:ElasticJob-Cloud 已停止维护,不推荐使用

LiteJob 架构详解

┌─────────────────────────────────────────────────────────────┐
│                    LiteJob 架构                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   ┌────────────┐  ┌────────────┐  ┌────────────┐        │
│   │  App Svr1  │  │  App Svr2  │  │  App Svr3  │        │
│   │ ┌────────┐ │  │ ┌────────┐ │  │ ┌────────┐ │        │
│   │ │ LiteJob│ │  │ │ LiteJob│ │  │ │ LiteJob│ │        │
│   │ │调度+执行│ │  │ │调度+执行│ │  │ │调度+执行│ │        │
│   │ └────┬───┘ │  │ └────┬───┘ │  │ └────┬───┘ │        │
│   └──────┼─────┘  └──────┼─────┘  └──────┼─────┘        │
│          │                 │                 │                │
│          └─────────────────┼─────────────────┘                │
│                            ▼                                  │
│                   ┌─────────────┐                          │
│                   │  ZooKeeper  │                          │
│                   │  (协调中心)  │                          │
│                   │             │                          │
│                   │ · 主节点选举  │                          │
│                   │ · 分片分配   │                          │
│                   │ · 节点发现   │                          │
│                   │ · 故障检测   │                          │
│                   └─────────────┘                          │
│                                                             │
└─────────────────────────────────────────────────────────────┘

核心组件

1. JobScheduler(作业调度器)

JobScheduler 是 ElasticJob 的核心,负责:

  • 初始化所有组件
  • 启动调度
  • 管理作业生命周期
java
public class JobScheduler {
    
    // 1. 初始化注册中心
    private final CoordinatorRegistryCenter registryCenter;
    
    // 2. 初始化作业配置
    private final JobConfiguration jobConfiguration;
    
    // 3. 初始化执行器
    private final JobExecutor jobExecutor;
    
    // 4. 初始化调度器
    private final SchedulerFacade schedulerFacade;
    
    public void init() {
        // 1. 注册作业节点到 ZooKeeper
        registerExecutor();
        
        // 2. 启动调度线程
        startScheduleThread();
        
        // 3. 注册作业完成监听器
        registerJobFinishedListener();
    }
}

2. RegistryCenter(注册中心)

注册中心使用 ZooKeeper,实现:

  • 作业节点管理
  • 主节点选举
  • 分片分配
  • 故障检测
java
// ZooKeeper 节点结构
/elastic-job
  /jobs
    /myJob
      /instances
        /192.168.1.1@-@12345  ← 执行实例
        /192.168.1.2@-@23456
      /sharding
        /0  ← 分片0 由实例1处理
        /1  ← 分片1 由实例2处理
      /leader
        /election
          /instance  ← 当前主节点

3. JobExecutor(作业执行器)

JobExecutor 负责执行具体的作业逻辑:

java
public class JobExecutor {
    
    public void execute(ShardingContexts shardingContexts) {
        List<ShardingContext> shardingList = shardingContexts.getShardingContextList();
        
        for (ShardingContext shardingContext : shardingList) {
            // 1. 获取分片参数
            String shardingParameter = shardingContext.getShardingParameter();
            
            // 2. 执行作业
            JobJobExecutionSegmentExecutionEvent event = new JobExecutionEvent(tracingId);
            executionService.execute(
                () -> {
                    // 调用作业类执行
                    jobClass.execute(shardingContext);
                },
                shardingContext,
                event
            );
        }
    }
}

工作流程

┌─────────────────────────────────────────────────────────────┐
│                    LiteJob 工作流程                        │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   1. 启动阶段                                               │
│   ┌─────────────────────────────────────────────────────┐  │
│   │                                                      │  │
│   │  App Server ──▶ 初始化 JobScheduler                │  │
│   │      │                                              │  │
│   │      ▼                                              │  │
│   │  ZooKeeper ──▶ 注册实例节点                        │  │
│   │      │                                              │  │
│   │      ▼                                              │  │
│   │  ZooKeeper ──▶ 参与主节点选举                        │  │
│   │                                                      │  │
│   └─────────────────────────────────────────────────────┘  │
│                           │                                 │
│   2. 调度阶段                                               │
│   ┌─────────────────────────────────────────────────────┐  │
│   │                                                      │  │
│   │  主节点 ──▶ 读取 cron 表达式,计算下次触发时间        │  │
│   │      │                                              │  │
│   │      ▼                                              │  │
│   │  主节点 ──▶ 分配分片                                  │  │
│   │      │                                              │  │
│   │      ▼                                              │  │
│   │  ZooKeeper ──▶ 更新分片节点状态                      │  │
│   │      │                                              │  │
│   │      ▼                                              │  │
│   │  所有节点 ──▶ 读取分片分配                           │  │
│   │      │                                              │  │
│   │      ▼                                              │  │
│   │  执行 ──▶ 每个节点执行自己负责的分片                  │  │
│   │                                                      │  │
│   └─────────────────────────────────────────────────────┘  │
│                                                             │
└─────────────────────────────────────────────────────────────┘

主节点选举

ElasticJob 使用 ZooKeeper 的临时节点实现主节点选举:

java
public class LeaderService {
    
    public void electLeader() {
        // 1. 创建临时节点
        String nodePath = "/leader/election/instance";
        
        try {
            zkClient.createEphemeral(nodePath, instanceId);
            // 创建成功,说明成为主节点
            leaderNode = instanceId;
        } catch (Exception e) {
            // 节点已存在,说明已有主节点
            // 监听主节点变化
            addConnectionStateListener(new ConnectionStateListener() {
                @Override
                public void stateChanged(ConnectionState state) {
                    if (state == ConnectionState.CONNECTED) {
                        // 重新选举
                        electLeader();
                    }
                }
            });
        }
    }
}

与 XXL-Job 对比

维度ElasticJob LiteXXL-Job
架构去中心化调度中心模式
调度中心必须部署
协调组件ZooKeeper数据库
分片支持原生支持支持
学习成本
运维复杂度高(需要 ZooKeeper)
适用场景大数据、分片复杂通用场景

总结

组件作用
JobScheduler核心调度器,管理作业生命周期
RegistryCenterZooKeeper 注册中心,协调分布式
JobExecutor执行具体的作业逻辑
LeaderService主节点选举,确保调度唯一性
ShardingService分片分配,将任务分配到各节点

思考题

ElasticJob 的去中心化架构和 XXL-Job 的调度中心模式,各有什么优缺点?

在什么场景下,去中心化架构更有优势?

基于 VitePress 构建