Files
AIclinicalresearch/docs/02-通用能力层/系统级异步架构风险剖析与演进技术蓝图.md
HaHafeng dc6b292308 docs(asl): Complete Tool 3 extraction workbench V2.0 development plan (v1.5)
ASL Tool 3 Development Plan:
- Architecture blueprint v1.5 (6 rounds of architecture review, 13 red lines)
- M1/M2/M3 sprint checklists (Skeleton Pipeline / HITL Workbench / Dynamic Template Engine)
- Code patterns cookbook (9 chapters: Fan-out, Prompt engineering, ACL, SSE dual-track, etc.)
- Key patterns: Fan-out with Last Child Wins, Optimistic Locking, teamConcurrency throttling
- PKB ACL integration (anti-corruption layer), MinerU Cache-Aside, NOTIFY/LISTEN cross-pod SSE
- Data consistency snapshot for long-running extraction tasks

Platform capability:
- Add distributed Fan-out task pattern development guide (7 patterns + 10 anti-patterns)
- Add system-level async architecture risk analysis blueprint
- Add PDF table extraction engine design and usage guide (MinerU integration)
- Add table extraction source code (TableExtractionManager + MinerU engine)

Documentation updates:
- Update ASL module status with Tool 3 V2.0 plan readiness
- Update system status document (v6.2) with latest milestones
- Add V2.0 product requirements, prototypes, and data dictionary specs
- Add architecture review documents (4 rounds of review feedback)
- Add test PDF files for extraction validation

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-23 22:49:16 +08:00

5.3 KiB
Raw Permalink Blame History

🎯 系统级异步架构风险剖析与演进技术蓝图 (V2.0 定稿版)

文档性质: 架构决策与研发执行规范 面向受众: 架构师、技术负责人、中高级后端研发 背景: 随着 ASL 工具 3 等批量耗时任务的引入,系统正从“单体异步”转向“分布式扇出 (Fan-out)”架构。 核心目标: 解决多实例部署下的计数丢失、状态撕裂与事件孤岛风险,建立工业级的分布式任务处理标准。

💡 一、 问题的本质:架构的分水岭

在分布式系统设计中,异步任务的复杂度随业务颗粒度呈指数级跃迁。我们必须将任务划分为两个完全不同的等级:

维度 Level 1单体任务 (现有标准) Level 2分布式扇出 (演进方向)
典型案例 工具 C 解析 1 个 Excel 工具 3 批量提取 100 篇文献
工作流 1 个触发 -> 1 个 Worker -> 结束 1 个触发 -> 1 个 Manager -> N 个子 Worker
多实例安全性 。依靠 pg-boss 行锁。 。子任务跨机器,必须处理原子性聚合。
容错代价 。失败重跑 40 秒。 极大。若无扇出,第 99 篇失败会导致前 98 篇全废。
系统影响 局部影响。 全系统级风险API 熔断、数据库连接耗尽)。

🔍 二、 核心风险深度剖析 (The Risks)

在多 SAE 实例Multi-Pod部署环境下若不严格执行 V2.0 规范,将面临以下系统性崩溃风险:

1. 统计数据的“幻影覆盖” (Race Condition)

  • 现象: 当 100 个子任务在不同 Pod 同时完成时,如果采用 count = count + 1 的读写逻辑,多个进程会读到相同的旧值并覆盖写入。
  • 后果: 进度条卡死、统计金额错误、任务永远无法触发“完成”回调。

2. “最后一个人关灯”难题 (The Terminator Problem)

  • 现象: 缺乏全局协调逻辑。Manager 派发完任务就结束了,子任务各自为政。
  • 后果: 系统不知道“这组任务”什么时候算真正结束,无法自动触发后续的报告生成或通知发送。

3. SSE 实时日志的“物理隔绝” (Event Silos)

  • 现象: 用户的浏览器连接在 Pod A但执行任务的 Worker 运行在 Pod B。Pod B 产生的日志在 Pod A 的内存里完全不存在。
  • 后果: 页面显示“处理中”但日志区一片空白,用户因感知不到进度而频繁刷新,造成更大的后端冲击。

🛠️ 三、 全系统演进执行建议 (The Guidelines)

为了消除上述风险,全平台所有异步模块必须强制对齐以下 4 项架构红线:

🚨 规范 1强制执行数据库级原子操作

禁止在异步代码中使用任何内存层面的数学运算来更新数据库。

  • 错误写法: data: { count: task.count + 1 }
  • 正确标准 (Prisma) ```typescript await prisma.task.update({ where: { id: taskId }, data: { successCount: { increment: 1 } } });

🚨 规范 2引入“Last Child Wins”收口机制

在分布式环境下,必须由最后一个完成任务的进程负责“关灯(翻转父任务状态)”。

  • 执行逻辑: 每个子任务在执行完【原子递增】后,必须同步读取更新后的结果。
  • 判定公式: if (updatedTask.successCount + updatedTask.failedCount === updatedTask.totalCount)
  • 后续: 若条件成立,该实例负责将 Task.status 改为 completed 并触发 SSE 完成事件。

🚨 规范 3从 EventEmitter 转向跨实例消息总线

彻底封杀多实例环境下的单机 EventEmitter 实时推送。

  • Postgres-Only 方案: 充分利用 PostgreSQL 的 LISTEN/NOTIFY 机制。
  • 工作流: 1. Worker 发送 NOTIFY channel_name, payload。 2. 所有 API 节点在启动时 LISTEN 该频道。 3. 收到通知的 API 节点检查本地内存,若存在对应 taskId 的 SSE 客户端,则执行推送。

🚨 规范 4极端场景下的“背压限制”与超时阻断

  • 全局限流: 针对昂贵的外部 API如 MinerU必须使用 pg-boss 的 teamConcurrency 进行数据库级全局限流,严禁使用单机 P-Queue。
  • 超时阻断: 所有跨网络请求必须强制设置 timeout建议 ≤ 90s防止外部接口假死扣住 pg-boss 队列名额,导致系统死锁。

📅 四、 路线图:如何平滑过渡?

  1. 实验场 (M1/M2) 以“ASL 工具 3”作为首个 V2.0 规范试点,沉淀出通用的 FanOutHelper 和 ListenNotifyService。
  2. 基建化: 将上述成功代码抽离,封装入 common/jobs 和 common/streaming 能力层。
  3. 全量覆盖: 发布《Postgres-Only 异步任务处理指南 v2.0》,要求后续所有涉及“批量处理”的模块(如 IIT Agent、批量报告生成严格照此执行。

🏁 架构师寄语

工具 3 的出现不是增加了复杂度,而是帮我们掀开了分布式环境下一直被掩盖的风险盖子。 与其在上线后通过熬夜排查“幽灵 Bug”不如现在多审核一次在文档阶段就打好地基。 请研发团队认真研读此蓝图,这套规范将让我们的系统从“能跑通”进化到“金身不坏”。