【发布时间】:2018-06-14 09:50:08
【问题描述】:
我的问题与这个问题有一些相似之处: Why do we need message brokers like RabbitMQ over a database like PostgreSQL?
在我目前的(半专业)项目中,我还需要决定是否选择数据库、基于消息代理的(例如使用 RabbitMQ),甚至是完全不同的解决方案。
让我们想象两个工具,工具 A 和工具 B。 每当工具 A 运行并完成时,可能工具 B 需要做一些事情。工具 A 的执行需要一些时间(> 60 秒),而且工具 B 通常无事可做。工具A 为工具 B 提供了一些元数据,因此工具 B 知道该做什么。
基于消息的解决方案:建立一个工具 B 正在消费的消息队列。如果工具 A 已执行并且工具 B 应该运行,工具 A 会向工具 B 接收的队列发布一条消息(包括元数据),以便工具 B 使用消息中的元数据运行。 p>
数据库解决方案:每当工具 A 运行时,它都会添加一条数据库记录,例如时间戳、元数据和状态“正在运行”。如果工具 A 已执行并且工具 B 应该运行,它会将 DB 记录状态更新为“NEXT_TOOL_B”。工具 B 不断地在数据库中查询具有“NEXT_TOOL_B”状态的记录。万一它发现了什么,工具 B 将使用数据库记录中的元数据运行。
虽然我知道数据库解决方案的缺点,例如来自工具 B 的不断轮询,我错过了它在基于消息的解决方案中的一个功能:
每当使用第 3 个工具时,就说工具 C,例如一个控制面板用户界面,想知道当前状态,也可以随时查询数据库,如果工具A仍在工作,它会找到“正在运行”状态。在消息解决方案中,我真的看不到“监控”状态的方法,除非完成消息将在队列中。
所以我的问题是,您能想出使用消息或任何其他无需轮询的方式来实现此目的的方法吗?
【问题讨论】:
-
我不确定你为什么反对这两个工具。消息队列可以帮助您编写松耦合的应用程序(或应用程序组件)和数据库来保存状态。您需要获取一个状态,从数据库中获取它。您需要使您的组件进行通信,使用消息队列。如果由于管理开销而不想要两者,则必须做出选择并接受缺点。因此,这是软件工程社区的问题,而不是 stackoverflow。
-
有几篇文章,例如this one,其中消息队列比数据库更适合工具间通信。当然,像锁定这样的数据库提到的缺点在很大程度上取决于应用程序的规模。最后,作为一名控制工程师而不是软件开发人员,我希望得到像你这样的反馈,我可能想要一个混合解决方案,而不是使用一个或另一个,而是两者兼而有之。
-
假设您想将工具 A 扩展为 10 个实例,将工具 B 扩展为 10 个实例。您如何确保工具 A 中的任务只处理一次?所有 10 个都将轮询数据库,第一个找到就绪任务的人必须锁定任务表并在持有锁的同时对其进行更新......不是很好。虽然一些工具 A 实例想要编写一个新任务,但等待并且失败了......您可能已经丢失了数据......而使用消息队列 - 您只有所有 10-100 个(没关系)工具实例B 坐在一个工作队列上,只有一个实例会收到消息。
标签: database rabbitmq message-queue