Skip to content

automation/approvals: 多副本集群下审批流每级节点(除首级)被重复创建 —— approve 后恢复读到滞后一拍的流运行态,同级要批两次(单副本零重复) #13617

Description

@baozhoutao

TL;DR(人话)

多副本集群(redis 集群驱动 + LB 轮询)下,flow 审批流每一级审批(除第一级)会被重复创建一次:核准当前节点后,平台重建了同一个节点(同 flow_run_id、同 flow_node_id 出现 approved + pending 两行),同一审批人要把同一级批两遍才能推进。单副本同库同流零重复。流最终能走完、终态正确,但审批人会看到重复待办。

版本与环境

  • objectos-ee 镜像 4.1.1(内建 runtime 17.2.0),@objectstack/automation / @objectstack/service-cluster-redis 随镜像
  • 拓扑:traefik 轮询 → 3 个 app 副本,共享 postgres:16 + 共享 redis:7,OS_CLUSTER_DRIVER=redis
  • 单副本(停掉 2 个副本,同一库)对照:零重复 —— 集群特有

最小复现

任意 record_change 触发的多级审批流(复现用的流:三级,节点 lv1→lv2→lv3,approvers 分别为 field / position / position):

  1. 提交记录触发流 → 建 lv1 审批请求(恰 1 张,这一步正常);
  2. 核准 lv1 → 正常推进,建 lv2;
  3. 核准 lv2 → 平台又建了一个 lv2(pending),而不是 lv3;
  4. 再核准 lv2(第二次)→ 建 lv3;核准 lv3 → 又建一个 lv3;再核准 → 流结束。

三级流实际产生 5 个审批节点(lv1×1、lv2×2、lv3×2)。sys_approval_request 留痕:

lv1_dept_head | approved   (同一 flow_run_id)
lv2_gm        | approved
lv2_gm        | approved   ← 重复
lv3_finance   | approved
lv3_finance   | approved   ← 重复

时间线特征:重复节点的 created_at 与上一节点的 completed_at 相差 ~60ms(核准的恢复动作当场重建了当前节点)。

判别与机理推断

  • 单副本对照(同库、同流定义、新记录):恰好 3 节点零重复 ⇒ 排除流定义/项目侧因素;
  • 每次核准请求经 LB 轮询落到不同副本。现象与「approve 后的流程恢复读到了滞后一拍的运行状态(副本内存缓存的 flow run 检查点未跨节点同步)」完全吻合:恢复方以为当前还在上一节点,于是把"下一节点"(=其实是刚批完的节点)再建一遍;
  • 同环境启动日志有 MetadataClusterBridgePlugin: metadata service does not expose attachClusterPubSub(); cross-node cache invalidation disabled —— 疑与该缓存失效通道缺失同族。

期望

集群下核准节点 N 应推进到 N+1,不应重建 N;流运行态的恢复应以共享存储(或跨节点失效后的重读)为准,不受处理副本的内存缓存影响。

旁证(同环境其余集群面均正常)

record_change 触发本身恰跑一次(1 次提交只建 1 张审批请求);定时任务 redis fence 选主只跑一次;通知每事件恰 1 条 —— 唯独审批流的 approve-resume 链路出现滞后。

我们没有做的事

应用侧无 workaround(不吞重复节点)。当前只能接受"每级多批一次"或把审批链路收单副本。


Part of steedos-labs/os-project-titanwind-ehr(deploy-ee 集群实测第六轮发现;单副本对照零重复)

Metadata

Metadata

Assignees

Labels

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions