请教一下这种系统到底应该怎么设计 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
Vcide
V2EX    程序员

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

  •  
  •   Vcide 2024-01-19 11:49:41 +08:00 2414 次点击
    这是一个创建于 633 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在 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 来更新子任务的状态呢?

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

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

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

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

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


    两种情况,A 都只做命令控制和状态查询,不参与流程处理,和 BCD 通过数据库交换信息
    auh
        9
    auh  
       2024-01-20 03:20:50 +08:00
    1. A 系统看上去像是个任务管理者。包含查询结果的功能。那么,当然是需要被通知的。通知的方式,如果是数据库的话,A 系统可以有定时任务处理。如果,A 系统被通知,采用网络回调通知。那么,存在网络问题,显然,还是 task+回调,的形式,进行的结果。所以,A 系统,至少被数据库通知到。才能保证不丢失消息。叠回调,才能更快吧。
    2. 没感觉。
    3. 和 1 一样。
    nolog
        10
    nolog  
       2024-01-23 17:52:58 +08:00
    1.感觉可以 B 通知 MQ ,然后 MQ 通知 C 做处理
    2.手动 ACK 没毛病
    3.看情况吧,如果 B 、C 、D 需要更新状态很频繁并且 QPS 很大的话,并不建议由 A 来统一管理,各子模块自己更新自己的数据状态更好点,这样模块边界比较明确。
    Vcide
        11
    Vcide  
    OP
       2024-03-13 15:51:37 +08:00
    谢谢大家的建议和意见,非常有帮助! 由于我们处理的流程较为固定, 所以目前的处理方法是使用 mq 和多个服务来进行手工编排,各个模块分开管理自己的状态了. 对于 B 的处理方法采用了 @giiiiiithub 的方法, 由于项目时间的限制, 没有使用项目编排框架的机会, 如果后续有新的变化, 会继续在这里向大家更新.
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3470 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 04:42 PVG 12:42 LAX 21:42 JFK 00:42
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86