对何时使用 JMS(或一般的队列)与数据库感到困惑
Posted
技术标签:
【中文标题】对何时使用 JMS(或一般的队列)与数据库感到困惑【英文标题】:Confused as to when you would use JMS (or a queue in general) versus a database 【发布时间】:2011-01-02 23:11:20 【问题描述】:当您将消息存储在队列中时,它不是更多的是元数据信息,因此从队列中拉出的人知道如何处理数据吗?队列中的实际信息并不总是包含所有信息。
假设您有一个像 Twitter 这样的应用程序,每当有人发布消息时,您仍然需要将实际消息文本存储在数据库中对吗?
队列将更多地用于向其他订阅者广播新消息已到达,然后这些服务可以采取进一步的行动。
或者你真的可以将推文文本也存储在队列中吗? (或者你可以,但那会很愚蠢?)
队列消息是否可以包含状态字段,哪些订阅者可以在处理他们的工作流程部分时进行更改? (或者你会在数据库中这样做吗?)
只是想弄清楚何时使用队列与数据库。
【问题讨论】:
【参考方案1】:当一个进程想要农场数据并将该数据处理到另一个进程(可能在不同的主机上)时,有两种策略:
将所有数据填充到队列项中,让接收应用程序担心将其存储在数据库中,以及进行任何其他处理。
更新您的数据库,然后将一条小消息排队到另一个进程,以通知它有新数据需要处理。
有许多因素可用于决定采用哪种策略:
如果您的数据库完全是 ACID(希望如此),但您的排队系统 (QS) 不是,那么您的数据在数据库中会更安全。即使队列消息在服务器崩溃中丢失,您也可以运行脚本来处理在数据库中找到的未处理数据。这将是选项 2 的情况。
如果您的数据非常大(例如,1 MB 或更多),那么给您的 QS 带来负担可能会很残酷。如果它是持久的,您最终将两次写入数据,首先写入 QS 的持久化器,然后写入数据库。这可能会拖累性能并影响您选择选项 1。
如果您的数据库速度很慢,或者您的应用程序的前端甚至无法访问,那么选项 1 就是这样。
如果您的第二个进程要处理数据但不将其存储在数据库中,那么选项 1 可能是要走的路。
想不出来了,但我希望你能明白。
【讨论】:
【参考方案2】:一般来说,队列用于通过缓冲无法立即处理的传入请求来“平滑”发布速率与消耗速率。队列通常由某种非易失性存储(例如数据库表)支持。所以区别不是很明显。
当您想针对“队列”执行多次搜索或提供丰富的报告时,请使用数据库。
【讨论】:
【参考方案3】:我建议您查看 Gregor Hophe 的书 Enterprise Integration Patterns,它解释了基于消息传递方法的许多不同模式。
【讨论】:
【参考方案4】:我在上一份工作中广泛使用了 JMS,我们在机器之间传递数据。最后,我们同时发送和存储数据;但是,我们存储的数据远少于发送出去的数据。我们有很多围绕真实价值的元数据。
我们将 JMS 用作简单的消息传递服务,它在这方面工作得很好。但是,您不想使用 JMS 来存储您的数据,因为它没有持久性(除了能够记录和重放消息之外)。
JMS 为您提供的主要优势之一是能够以正确和适当的顺序发送您的消息,并确保每个人都按该顺序接收它们。这使得同步变得容易,因为大部分消息处理都是为您完成的。
【讨论】:
【参考方案5】:我的理解是 Twitter 将同时使用 DB 和 JMS。首先,当推文被写入时,它将存储在数据库中,这就是它在留言板中的显示方式。但是,由于这是发布推文时的发布者/订阅者模型,因此它将被发送给订阅者。所以这两个项目都将被使用。
【讨论】:
【参考方案6】:我认为您的推特示例很好。您需要用于长期数据的数据库。将推文放入消息中没有多大意义,因为它必须进入数据库。但是,如果您正在运行一个聊天室,那么您可以继续将消息放入 JMS 队列中,因为您不会将它长期存储在任何地方。
不是你不能把推文放在 JMS 中,而是你需要把它放在数据库中。
【讨论】:
【参考方案7】:只要您可以使用“即发即弃”模式,我就会使用队列。在您的 Twitter 示例中,我将使用队列发布来自客户端的消息。然后,队列处理器可以在到达时将其存储到数据库中。
如果您需要某种即时的成功/失败状态,那么消息队列不适合您。
【讨论】:
以上是关于对何时使用 JMS(或一般的队列)与数据库感到困惑的主要内容,如果未能解决你的问题,请参考以下文章
对 python 装饰器感到困惑。何时/如何称呼他们? [复制]