18

在实际生产环境中,我一直在体验消息传递系统的优点和缺点,我必须承认,一个组织良好的表或表模式每次都比任何其他形式的消息队列都要好,因为:

  1. 数据永久存储在表中。我见过很多 java (jms) 应用程序由于未捕获的异常或其他错误而在途中丢失或消失消息。
  2. 队列往往会被填满。相反,数据库存储实际上是无限的。
  3. 表格很容易访问,而您必须使用深奥的工具从队列中读取。

您对每种方法有何看法?

4

5 回答 5

35

每次都跳动这句话完全取决于您的要求。当然,它不会每次都击败每个人。

如果您正在构建一个已经在使用数据库的单个系统,那么您没有非常高的性能吞吐量要求并且您不必与任何其他团队或系统进行通信,那么您可能是对的。

对于简单、低吞吐量、主要是单线程的东西,数据库是消息队列的完全替代品。

消息队列的亮点在于何时

  • 你想要一个高性能、高并发和可扩展的负载均衡器,这样你就可以在许多服务器/进程上同时处理每秒数万条消息(使用数据库表,你很幸运每秒可以处理几百个并处理多个线程非常困难,因为一个进程往往会锁定消息队列表)
  • 您需要使用不同的数据库在不同的系统之间进行通信(因此不必将系统数据库的写访问权限分发给不同团队中的其他人等)

对于具有单个数据库、团队和相当适中的性能要求的简单系统 - 请务必使用数据库。为工作使用正确的工具等。

然而,消息队列在大型组织中大放异彩,那里有许多需要相互通信的系统(因此您不希望业务数据库成为故障的中心点或版本地狱的地方),或者当您有高性能要求。

就性能而言,消息队列总是胜过数据库表——因为消息队列是专门为这项工作设计的,不依赖于悲观表锁(这是数据库实现队列所必需的——进行负载平衡)并且好的消息队列会执行预先加载消息到队列以避免数据库的网络开销

同样——你永远不会使用数据库在你的 Web 服务器上对 HTTP 请求进行负载平衡——因为它太慢了——如果你对负载平衡器有很高的性能要求,你也不会使用数据库。

于 2008-11-03T12:10:06.100 回答
9

我首先使用了表,然后在(如果)有原因时重构为一个成熟的 msg 队列 - 如果您的设计合理,这将是微不足道的。

最大的好处是 a.) 它更容易,(b. 这是一个更好的审计跟踪,因为您有其他表要加入,c.) 如果您非常了解数据库工具,它们比 Message Queue 工具更容易使用, d.) 在您的应用程序已经存在的上下文中设置测试/开发环境通常会更容易一些(如果同样熟悉的话)。

哦,还有 e.) 也许对于您和其他人来说,它不是另一个需要学习、安装、配置、管理和支持的产品。

IMPE,它同样可靠,可断开连接,如果需要更多可扩展性,您可以转换。

于 2008-11-01T17:44:21.123 回答
9
  1. 数据永久存储在表中。我见过很多 java (jms) 应用程序在它们的途中因未捕获的异常或其他错误而丢失或消失消息。

    哪个 JMS 实现?Sun 销售不会丢失消息的可靠队列。也许您刚刚购买了符合 JMS 标准的俗气产品。IBM 的 MQ 非常可靠,并且有 JMS 库可以访问它。

  2. 队列往往会被填满。相反,数据库存储实际上是无限的。

    嗯...如果您的队列已满,听起来好像有什么东西坏了。如果您的应用程序崩溃,那不是一件好事,队列与此关系不大。如果您购买了一个非常糟糕的 JMS 实现,我可以看到您可能对它不满意的地方。这是一个竞争激烈的市场。寻找更好的队列管理器。Sun 的 JCAPS 有一个非常好的队列管理器,以前是 SeeBeyond 消息队列。

  3. 表格很容易访问,而您必须使用深奥的工具从队列中读取。

    这不符合我的经验。表是通过这种特殊的“其他语言”(SQL) 访问的,并且要求我了解从表到对象的结构映射以及从 VARCHAR2 到字符串的数据类型映射。此外,我必须使用某种访问层(JDBC 或使用 JDBC 的 ORM)。这看起来非常非常复杂。使用简单的发送和接收通过 MessageConsumers 和 MessageProducers 访问队列。

于 2008-11-01T18:51:57.333 回答
7

听起来您遇到的问题似乎不是消息传递所固有的,而是消息传递系统实现不善的产物。构建消息系统是否比构建数据库系统更难?是的,如果您所做的只是构建数据库系统。

  • 将消息丢失给未捕获的异常?这几乎不是消息队列的错。您使用的应用程序设计不佳。他们在处理完成之前从队列中删除消息。他们没有使用交易或日记。
  • 数据库存储“几乎无限”时消息队列已满?你说的好像管理磁盘空间是数据库不需要的东西。消息队列服务器需要管理,就像数据库服务器一样。
  • 从队列中读取的深奥仪器?也许如果您发现异步方法深奥。也许如果您发现序列化和反序列化深奥。(至少,这些是我在学习消息传递时发现的深奥的东西。就像许多看似深奥的技术一样,一旦你理解它们,它们实际上就很平凡,而理解它们是经验丰富的开发人员教育的重要组成部分。)

使其优于数据库的消息传递方面:

  • 异步处理。 当新消息到达时,消息队列会通知等待进程。要在数据库中完成此功能,等待进程必须轮询数据库。
  • 关注点分离。 通信通道与消息内容的实现细节分离。只有发送者和接收者需要知道给定消息中数据流的格式。
  • 容错。. 当服务器之间的连接断断续续时,消息传递可以发挥作用。消息队列可以在本地存储消息,并且仅在连接处于活动状态时将它们转发到远程服务器。
  • 系统集成。 至少在 Windows 世界中,消息传递是内置在操作系统中的。它使用操作系统的安全模型,通过操作系统的工具等进行管理。

如果您不需要这些东西,则可能不需要消息传递。

这是消息传递应用程序的一个简单示例:我现在正在构建一个系统,其中分布在多个网络中的用户正在输入用于产生打印输出的相当复杂的事务集。输出生成的计算成本很高,并且不是其工作流程的一部分;即用户不在乎何时生成输出,只是它确实如此。

因此,我们将事务序列化为消息并将其放入队列中。在服务器上运行的进程从队列中获取消息,生成输出,并将输出存储在成像系统中。

如果我们使用数据库作为我们的消息存储,我们必须想出一个模式来存储目前只有发送者和接收者关心的事务格式,我们需要确保网络上的每个工作站都有永久的与数据库服务器的持久连接,我们将无法在多个服务器之间分配此事务负载,并且我们的输出服务器每天必须查询数据库数千次,等待是否有新的作业要处理。

于 2008-11-01T21:03:02.563 回答
2

队列提供可靠的消息传递。队列的存储转发、断开连接的特性使其比数据库更具可扩展性,更不用说更健壮了。

队列不应该真正用于信息的永久存储——最好将它们视为临时收件箱,与数据库不同。

于 2008-11-01T17:27:57.037 回答