我的问题与这个问题有一些相似之处: Why do we need message brokers like RabbitMQ over a database like PostgreSQL?
在我目前的(半专业)项目中,我还决定是去数据库,基于消息代理(例如使用RabbitMQ)还是完全不同的解决方案。
让我们想象2个工具,工具A和工具B. 每当工具A运行并完成时,可能可以为工具B执行操作。工具A的执行需要一段时间(> 60秒),并且通常对工具B没有任何操作。工具A为工具B提供了一些元数据,因此工具B知道该怎么做。
基于消息的解决方案:建立工具B正在使用的消息队列。如果工具A已执行且工具B应运行,工具A会将消息(包括元数据)发布到工具B接收的队列中,以便工具B将使用消息中的元数据运行。
数据库解决方案:每当工具A运行时,它都会添加一个数据库记录,例如:时间戳,元数据和状态" RUNNING"。如果工具A已执行且工具B应运行,则会将DB记录状态更新为" NEXT_TOOL_B"。工具B不断向DB查询" NEXT_TOOL_B"状态。如果找到某些内容,工具B将使用DB记录中的元数据运行。
虽然我知道数据库解决方案的缺点,例如工具B的常量轮询,我在基于消息的解决方案中遗漏了它的一个特性:
每当第三个工具,比如工具C,例如一个控制面板用户界面,想知道当前状态,它也可以随时查询数据库,它会找到一个" RUNNING"状态如果工具A仍在工作。在消息解决方案中,我并没有真正看到一种方法来监控"状态,除非完成消息将在队列中。
所以我的问题是,您是否可以考虑使用消息或任何其他没有轮询的方法实现此目的?
答案 0 :(得分:6)
问题中描述的场景是系统的场景,它由多个不同的部分组成,它们协同工作以实现功能。在这种情况下,您有三个不同的进程{A,B,C}
,以及数据库和可选的消息队列。作为其存在目的的一部分,所有系统接受一个或多个输入,执行一些过程,并产生一个或多个输出。在您的情况下,您需要的输出之一是系统的状态及其处理,这不是一个完全不合理的事情。
队列或数据库?
现在,直到你的问题。为什么使用消息队列而不是数据库?两者都是系统的类似组件,因为它们执行一些存储容量。您可能会在冰箱制造工厂中提出同样的问题 - 何时在装配线上使用货架而不是仓库更有意义?
数据库就像仓库一样 - 它们旨在容纳许多不同的东西并使它们保持相对直接。一个好的仓库允许用户快速查找仓库中的东西,并避免丢失零件和材料。如果它进入,它可以很容易地退出,但不是立即。
另一方面,消息队列就像位于装配线中操作员站附近的货架。零件从之前的操作累积到那里等待由运行该站的人消耗。这些架子设计用于容纳少量相同的东西 - 就像软件系统中的消息队列一样。它们靠近工人,所以当下一部分准备好工作时,它可以很快被检索(而不是去仓库,可能需要几分钟或更长时间)。此外,工人可以立即看到货架上的物品 - 如果货架是空的,工人可能会休息并等待它再次累积一部分或两部分。
最后,如果工厂的一部分严重过度生产(当发生这种情况时我们不喜欢它,因为它表明浪费),那么货架将会不堪重负,而且需要超额被放入仓库。信不信由你,这种情况一直发生在工厂 - 有时候车站会短暂停机,仓库可以作为长期缓冲。
何时使用其中一种?
所以 - 回到问题。如果您希望消息的生成通常与消息的消耗相匹配,则需要使用消息队列,并且需要检索速度。你不希望事情长时间留在队列中。软件队列系统,例如RabbitMq,也执行一些非常特定的功能 - 比如确保一个处理器只处理一个作业,并且如果第一个处理器发生故障,它可以被另一个处理器拾取。
另一方面,您将使用数据库来处理需要跨多个处理步骤持久化状态的事物。您的工作状态是应该存储在数据库中的完美示例。继续工厂类比 - 将其视为在每个步骤完成后发送回生产计划员的报告。生产计划员将把它保存在数据库中。
您可能还希望在队列可能已满的情况下使用数据库,或者在一个作业步骤与另一个作业步骤之间数据不丢失的情况下使用数据库。例如,制造工厂通常将其成品存储在仓库中,等待运送给客户。在您的应用程序中使用数据库满足所有长期(超过几秒)的存储需求。
底线
大多数可扩展的软件系统都需要队列和数据库,关键是知道何时使用每个队列和数据库。
希望这有一定程度的意义。
答案 1 :(得分:0)
您可以使队列的生产者和消费者更新NoSQL数据库或RDBMS中的表。这将使您可以在任何给定时间查看请求的状态。它还将使您无需进行轮询即可利用推送消息的优势。
答案 2 :(得分:0)
免责声明:我是cluster-tasks-service-CTS
的作者,是提出的解决方案或其他使用其他相关工具时要考虑的模式。
问题是,从一般体系结构的角度来看,您描述的功能似乎需要两种解决方案:
我想说基于数据库的队列将是一个解决方案。与非基于DB的方法相比,基于DB的队列肯定遭受较低的吞吐量。但是,它为您带来一些好处,例如:
对于CTS
-这是一个基于DB的群集感知任务分配和管理系统(由使用中的应用程序提供并运行嵌入式程序),通过将工具B作为工具排队的任务运行,可以解决您的问题A在其处理结束时包含所有相关数据。
同时,工具C可以使用CTS
的API来检查任务的状态并根据需要可视化它们。