消息代理与数据库和监视

Cle*_*ens 3 database message-queue rabbitmq

我的问题与这个问题有一些相似之处: 为什么像PostgreSQL这样的数据库需要像RabbitMQ这样的消息代理?

在我目前的(半专业)项目中,我也决定是否要使用数据库,基于消息代理(例如使用RabbitMQ),甚至是完全不同的解决方案.

让我们想象两个工具,工具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,例如控制面板UI)想知道当前状态时,它也可以随时查询数据库,并且如果工具A仍在工作,它将发现"运行"状态.在消息解决方案中,我并没有真正看到"监视"状态的方法,除非完成消息将在队列中.

所以我的问题是,你能想到使用消息或任何其他方法实现这一点而不进行轮询吗?

the*_*yer 6

问题中描述的场景是一个系统,它由多个不同的部分组成,这些部分协同工作以实现功能.在这种情况下,您有三个不同的进程{A,B,C},以及数据库和可选的消息队列.作为其存在目的的一部分,所有系统接受一个或多个输入,执行一些过程,并产生一个或多个输出.在您的情况下,您需要的输出之一是系统的状态及其处理,这不是一个完全不合理的事情.

队列或数据库?

现在,直到你的问题.为什么使用消息队列而不是数据库?两者都是系统的类似组件,因为它们执行一些存储容量.您可能会在冰箱制造工厂中提出同样的问题 - 何时使用装配线上的货架而不是仓库更有意义?

数据库就像仓库一样 - 它们旨在容纳许多不同的东西并使它们保持相对直接.一个好的仓库允许用户快速查找仓库中的东西,并避免丢失零件和材料.如果它进入,它可以很容易地退出,但不是立即.

另一方面,消息队列就像位于装配线中操作员站附近的架子.零件从之前的操作累积到那里等待由运行该站的人消耗.这些架子设计用于容纳少量相同的东西 - 就像软件系统中的消息队列一样.它们靠近工人,所以当下一部分准备好工作时,它可以很快被检索(而不是去仓库,可能需要几分钟或更长时间).此外,工人可以立即看到货架上的物品 - 如果货架是空的,工人可能会休息并等待它再次积累一两件.

最后,如果工厂的一部分严重过度生产(当发生这种情况时我们不喜欢它,因为它表明浪费),那么货架将会不堪重负,并且需要将超出量放入仓库.信不信由你,这种情况一直发生在工厂 - 有时候车站会短暂停留,仓库可以作为长期缓冲区.

何时使用其中一种?

所以 - 回到问题.如果您希望消息的生成通常与消息的消耗相匹配,则需要使用消息队列,并且需要检索速度.你不希望事情在队列中停留很长时间.软件队列系统,例如RabbitMq,也执行一些非常具体的功能 - 比如确保作业只能由一个处理器处理,并且如果第一个处理器发生故障,它可以被另一个处理器拾取.

另一方面,您可以将数据库用于需要跨多个处理步骤持久化状态的数据库.您的工作状态是应该存储在数据库中的完美示例.继续工厂类比 - 将其视为在每个步骤完成后发送回生产计划员的报告.生产计划员将把它保存在数据库中.

您可能还希望在队列可能已满的情况下使用数据库,或者在一个作业步骤与另一个作​​业步骤之间丢失数据至关重要.例如,制造工厂通常将其成品存储在仓库中,等待运送给客户.使用数据库可以满足应用程序中所有长期(超过几秒)的存储需求.

底线

大多数可扩展的软件系统都需要队列和数据库,关键是知道何时使用每个队列和数据库.

希望这有一定程度的意义.