4. 任务编排模型:DAG(有向无环图)任务模型

在IAM平台的异步任务编排核心引擎中,任务之间的依赖关系与执行顺序不能依赖简单的线性队列。DAG(Directed Acyclic Graph,有向无环图)是业界公认的标准任务编排模型,它能够精确描述任务间的依赖约束,同时保证拓扑排序后不存在循环等待或死锁。

4.1 DAG任务模型定义

DAG由一组节点(Vertex)和一组有向边(Directed Edge)组成,且图中不存在任何环路。在IAM任务编排场景中:

  • 节点:代表一个可执行的原子任务单元,例如“同步LDAP用户”、“校验Token权限”、“更新角色缓存”。
  • 有向边:代表任务间的依赖关系,方向从前置任务指向后置任务,表示后置任务必须等待前置任务完成后才能开始执行。
核心约束: DAG中不允许存在环路。如果任务A依赖任务B,任务B又依赖任务A,则无法确定执行起点,引擎将拒绝提交该编排。

4.2 节点与边定义

在IAM引擎中,每个节点和边都携带丰富的元数据,用于权限校验、重试策略和状态追踪。下表列出了节点与边的核心属性:

元素 属性 类型 说明
节点 nodeId String 全局唯一任务标识
taskType Enum 任务类型:SYNC、VALIDATE、NOTIFY、ROLLBACK
requiredPermission String 执行该任务所需的IAM权限标识
maxRetries int 最大重试次数(默认3次)
timeoutSeconds int 任务超时时间(默认300秒)
边 fromNodeId String 前置任务节点ID
toNodeId String 后置任务节点ID
condition String 可选条件表达式,满足条件才触发下游

4.3 任务依赖关系解析

引擎在接收到DAG定义后,会执行依赖关系解析,主要包含以下步骤:

  1. 入度计算:遍历所有边,统计每个节点的入度(指向该节点的边数)。入度为0的节点即为起始节点。
  2. 依赖校验:检查每个节点的前置任务是否都在DAG中定义,防止出现“悬空依赖”。
  3. 权限聚合:从起始节点开始,沿边方向聚合路径上的权限要求,用于后续的权限校验。
  4. 环路检测:在拓扑排序过程中,如果最终排序结果中的节点数少于DAG总节点数,则说明存在环路,引擎拒绝执行。
实践建议: 在IAM平台中,依赖解析阶段应同时完成“权限预校验”。如果当前用户对DAG中某个节点不具备执行权限,应在提交阶段直接拒绝,而不是等到运行时才报错。

4.4 拓扑排序原理

拓扑排序(Topological Sorting)是DAG编排引擎的核心算法,它能够将DAG中的所有节点排列成一个线性序列,使得对于每一条有向边 (u → v),节点 u 在序列中都出现在节点 v 之前。常用的实现算法是Kahn算法(基于入度)。

Kahn算法伪代码如下:

function topologicalSort(graph):
    // 1. 初始化入度表
    inDegree = {node: 0 for node in graph.nodes}
    for edge in graph.edges:
        inDegree[edge.to] += 1

    // 2. 将入度为0的节点加入队列
    queue = [node for node in graph.nodes if inDegree[node] == 0]
    result = []

    // 3. 循环处理队列
    while queue is not empty:
        node = queue.pop(0)
        result.append(node)
        for neighbor in graph.getOutNeighbors(node):
            inDegree[neighbor] -= 1
            if inDegree[neighbor] == 0:
                queue.append(neighbor)

    // 4. 检查是否所有节点都已排序
    if len(result) != len(graph.nodes):
        throw "Graph contains a cycle"
    return result

拓扑排序的时间复杂度为 O(V + E),其中 V 为节点数,E 为边数。在IAM平台的典型场景中,单个DAG的节点数通常不超过200个,该算法可在毫秒级完成。

4.5 DAG任务编排示例

下面以一个IAM权限同步场景为例,展示DAG的结构与拓扑排序结果。该场景包含5个任务节点:

IAM权限同步DAG示例 A: 拉取LDAP用户 B: 校验Token C: 同步角色 D: 更新缓存 E: 通知下游 拓扑排序结果(Kahn算法): A → B → C → D → E 说明:A和B入度为0,可并行执行;C依赖A和B;D依赖C;E依赖D。

4.6 拓扑排序在IAM中的特殊处理

在IAM平台中,拓扑排序除了确定执行顺序外,还需要额外处理以下场景:

  • 并行度控制:入度为0的节点可以并行执行,但引擎需要根据线程池大小和系统负载动态控制并行度,防止资源耗尽。
  • 条件分支:某些边的condition属性可能为“仅当前置任务执行成功”或“仅当前置任务执行失败”,拓扑排序需要根据运行时状态动态调整后续节点的入度。
  • 权限传播:如果父节点具有高权限,子节点可能继承部分权限。拓扑排序过程中需要维护一个“权限上下文栈”,确保下游节点能够访问上游的临时凭证。
常见陷阱: 不要将拓扑排序与任务调度混为一谈。拓扑排序只负责确定依赖顺序,不负责决定何时执行。实际调度由引擎的调度器根据资源水位和优先级策略触发。

4.7 本章小结