2. 任务调度平台核心模型:实体关系与状态机

任务调度平台的核心在于对 Task(任务)、Job(作业)、Workflow(工作流)、Trigger(触发器) 和 Executor(执行器) 这五大实体的抽象与编排。理解它们之间的实体关系以及各自的状态机,是设计 OpenAPI 和事件驱动架构的基础。

2.1 五大核心实体定义

实体 英文 核心职责 生命周期特征
任务 Task 最小执行单元,定义具体的执行命令、脚本或 HTTP 请求 创建 → 就绪 → 运行 → 完成/失败
作业 Job 任务的逻辑容器,包含任务定义、重试策略、超时配置 启用 → 调度中 → 暂停 → 归档
工作流 Workflow 多个 Job 的有向无环图(DAG)编排,定义依赖与并行关系 草稿 → 发布 → 运行中 → 完成/终止
触发器 Trigger 驱动 Job 或 Workflow 执行的定时/事件源 绑定 → 激活 → 触发 → 失效
执行器 Executor 实际运行 Task 的物理或虚拟节点,负责资源隔离与日志采集 注册 → 在线 → 离线 → 注销

2.2 实体关系模型

五大实体通过以下关键关系构成调度平台的骨架:

  • Job 与 Task:一对多关系。一个 Job 包含一个或多个 Task,Task 在 Job 的上下文中按顺序或并行执行。
  • Workflow 与 Job:一对多关系。一个 Workflow 由多个 Job 组成,通过 DAG 边定义依赖(如 Job B 必须在 Job A 完成后启动)。
  • Trigger 与 Job/Workflow:多对多关系。一个 Trigger 可以绑定多个 Job 或 Workflow;一个 Job 也可以被多个 Trigger 触发。
  • Executor 与 Task:一对多关系。一个 Executor 在同一时刻可运行多个 Task,但每个 Task 只能分配给一个 Executor。
设计要点: 在 OpenAPI 设计中,Job 和 Workflow 是资源管理的核心端点(如 /api/v1/jobs、/api/v1/workflows),而 Task 实例通常作为子资源或事件流中的记录存在,不直接暴露为独立 CRUD 资源。
任务调度平台核心实体关系图 Trigger Workflow Job Task Executor 绑定 包含 包含 调度 调度 分配 说明:实线表示包含/绑定关系,虚线表示调度/分配关系。Trigger 可同时绑定 Workflow 和 Job。 Executor 是 Task 的运行载体,一个 Executor 可运行多个 Task。

2.3 核心状态机

每个实体都拥有独立的状态机,状态转换是事件驱动的核心。下面以 Task 和 Job 为例说明。

2.3.1 Task 状态机

当前状态 触发事件 下一状态 说明
PENDING 调度器分配 Executor RUNNING Task 被分配给一个在线 Executor
RUNNING 执行成功 SUCCESS Task 正常完成
RUNNING 执行失败 FAILED Task 异常退出
RUNNING 超时 TIMEOUT 超过 Job 配置的超时阈值
FAILED 重试策略触发 PENDING 重新进入调度队列
PENDING 手动取消 CANCELLED 用户通过 API 取消

2.3.2 Job 状态机

当前状态 触发事件 下一状态 说明
ENABLED Trigger 触发 RUNNING 开始执行 Job 内的 Task 序列
RUNNING 所有 Task 成功 COMPLETED Job 正常结束
RUNNING 任一 Task 失败且无重试 FAILED Job 整体失败
ENABLED 用户暂停 PAUSED 暂停后 Trigger 不再触发新实例
PAUSED 用户恢复 ENABLED 恢复调度
COMPLETED / FAILED 用户归档 ARCHIVED 历史数据清理
事件驱动设计提示: 每个状态转换都应发布对应的 Kafka 事件(如 task.state.changed、job.state.changed),下游消费者(如通知服务、监控面板)通过订阅这些事件实现解耦。
Task 状态机转换图 PENDING RUNNING SUCCESS FAILED TIMEOUT CANCELLED 分配 成功 超时 失败 取消 重试 说明:实线为正常转换路径,虚线为重试转换路径。重试次数耗尽后 FAILED 不再回到 PENDING。 每个状态转换都会触发 Kafka 事件,事件 key 为 taskId,value 包含新旧状态和时间戳。

2.4 实体关系在 OpenAPI 中的体现

在 OpenAPI 规范中,实体关系通过资源嵌套和引用表达:

# 示例:Job 资源定义(OpenAPI 3.0 片段)
components:
  schemas:
    Job:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        tasks:
          type: array
          items:
            $ref: '#/components/schemas/TaskRef'  # 引用 Task
        trigger_id:
          type: string
          description: "绑定的 Trigger ID"
        executor_group:
          type: string
          description: "执行器标签,用于调度匹配"
        state:
          $ref: '#/components/schemas/JobState'
    TaskRef:
      type: object
      properties:
        task_id:
          type: string
        order:
          type: integer
          description: "执行顺序"
避坑提示: 不要在 OpenAPI 中将 Workflow 的 DAG 结构直接嵌入 Job 定义。DAG 边应作为 Workflow 的独立子资源(如 /api/v1/workflows/{id}/edges),避免在更新 Job 时意外破坏依赖关系。

2.5 状态机与事件驱动的映射

每个状态转换对应一个 Kafka 事件主题(Topic),事件结构遵循统一格式:

事件主题 Key Value 关键字段 消费者示例
task.state.changed taskId oldState, newState, executorId, timestamp 日志服务、监控面板
job.state.changed jobId oldState, newState, triggerId, timestamp 通知服务、审计系统
workflow.state.changed workflowId oldState, newState, currentJobId, timestamp 可视化 DAG 面板
executor.heartbeat executorId status, load, runningTaskIds, timestamp 调度器、健康检查