请教一下这种系统到底应该怎么设计

338 天前
 Vcide

现在 PO 主正在设计这样一个系统,现有的设计包含 4 个模块.

四个模块具体如下:

  1. 1 个 SpringBoot 的后端模块 A,这个模块主要是实现 endpoint,提供对外使用的 API. 用户可以通过它上传文件并创建对应任务,选择后续的处理模块,并查询处理结果.
  2. 3 个独立的 Python 的 FastAPI 分析模块 B,C,D. 每一个处理起来都非常耗时,根据输入的不同,耗时在 30s 到 5 分钟左右不等. 其中 C 模块需要 B 模块处理后的结果,D 模块独立运行.

现在整个系统的工作流程类似于,用户通过 A 上传要处理的文件至服务器,并创建一个包含多个子任务的主任务,子任务是文件要不要被 B,C,D 处理. A,B,C,D 之间有一个消息队列作为中介进行消息的传递.

现在我的问题是:

  1. 对于 C 模块需要 B 模块的处理结果这件事,应该如何实现? 是 B 完成处理后通知 C, 还是通知 A,由 A 通知 C 呢?
  2. PO 主目前使用的是 RabbitMQ, 因为 B,C,D 都会消耗大量系统资源, 所以目前的设计是将它们对应的 perfetch_qos 设定为了 1, 并且在处理完之后手动 ack.感觉这样做很奇怪.有没有更好的处理方法呢?
  3. 假设 B,C,D 处理完之后是应该由它们更新数据库中子任务的状态,还是向 A 传递消息,由 A 来更新子任务的状态呢?

希望大家不吝赐教, 谢谢!

2023 次点击
所在节点    程序员
11 条回复
vczyh
338 天前
1. 模块的依赖和功能需要划分清楚,C 需要 B 的执行结果,为什么要通知 A ,如果你规定所有消息必须经过 A 或者因为 A 管理整个任务的生命周期,那就通知 A ,ABCD 只是 worker ,这样模块就清晰了,而且都用消息队列了,同时通知 A 和 C 也没问题。
2. 我认为手动 ACK 不奇怪吧,这个不太清楚
3. 同 1
rrfeng
338 天前
你这是个任务编排问题,跟信息交互关系不大。
要我说的话,丢到 jenkins ( or 类似工具)上去做个 flow 完事儿……
masterclock
338 天前
看起来是流程,所以 Temporal
jungledg
338 天前
想法和 1L 基本一致; 如果 A 需要感知所有任务处理状态、统筹分配的话,所有持久化状态改变都统一收口到 A 来做,反之就由各子系统来更新状态。
dayeye2006199
338 天前
最上面叠个 orchester 。所有的任务都走这个服务。
这个服务负责下发并且管理子任务之间的依赖。
lsk569937453
338 天前
由 A 统一来管理状态就行了。
1.上传视频文件到 A 。A 负责更新此任务的状态为"上传完毕"。A 会开启定时任务(1 分钟执行一次)检查任务状态。定时任务逻辑如下:

- a.从数据库里找到最新的"上传完毕"的任务,调用 B/D 的 API 检查是否有运行中的任务,没有的话,则调用 B/D 的 API ,提交任务。
- b.从数据库里找到最新的"B 已经处理完毕"的任务,调用 C 的 API 检查是否有运行中的任务,没有的话,则调用 C 的 API ,提交任务。

所有的提交任务都为异步提交。任务处理完毕直接到数据库中更新任务状态。
9c04C5dO01Sw5DNL
338 天前
B 处理完之后往特定通道发送通知消息,谁感兴趣谁订阅处理。
flmn
338 天前
你这个处理流程会变化么?会有多个不同的流程么?
如果是,那么,最好找个任务编排框架来处理

如果流程相对固定,可以使用 mq 和多个服务来手工编排,状态记到数据库


两种情况,A 都只做命令控制和状态查询,不参与流程处理,和 BCD 通过数据库交换信息
auh
338 天前
1. A 系统看上去像是个任务管理者。包含查询结果的功能。那么,当然是需要被通知的。通知的方式,如果是数据库的话,A 系统可以有定时任务处理。如果,A 系统被通知,采用网络回调通知。那么,存在网络问题,显然,还是 task+回调,的形式,进行的结果。所以,A 系统,至少被数据库通知到。才能保证不丢失消息。叠回调,才能更快吧。
2. 没感觉。
3. 和 1 一样。
nolog
334 天前
1.感觉可以 B 通知 MQ ,然后 MQ 通知 C 做处理
2.手动 ACK 没毛病
3.看情况吧,如果 B 、C 、D 需要更新状态很频繁并且 QPS 很大的话,并不建议由 A 来统一管理,各子模块自己更新自己的数据状态更好点,这样模块边界比较明确。
Vcide
284 天前
谢谢大家的建议和意见,非常有帮助! 由于我们处理的流程较为固定, 所以目前的处理方法是使用 mq 和多个服务来进行手工编排,各个模块分开管理自己的状态了. 对于 B 的处理方法采用了 @giiiiiithub 的方法, 由于项目时间的限制, 没有使用项目编排框架的机会, 如果后续有新的变化, 会继续在这里向大家更新.

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1009958

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX