消息系统中针对表的队列[关闭]
Posted
技术标签:
【中文标题】消息系统中针对表的队列[关闭]【英文标题】:Queues against Tables in messaging systems [closed] 【发布时间】:2010-09-20 07:49:17 【问题描述】:我在实际生产环境中体验过消息传递系统的优点和缺点,我必须承认,一个组织良好的表或表架构每次都能胜过任何其他形式的消息队列,因为:
-
数据永久存储在表中。我见过很多 java (jms) 应用程序由于未捕获的异常或其他错误而在途中丢失或消失消息。
队列往往会被填满。相反,数据库存储几乎是无限的。
桌子很容易访问,而您必须使用深奥的工具从队列中读取。
您对每种方法有何看法?
【问题讨论】:
【参考方案1】:队列提供可靠的消息传递。队列的存储转发、断开连接的特性使其比数据库更具可扩展性,更不用说更健壮了。
队列不应该真正用于信息的永久存储 - 最好将它们视为临时收件箱,不像数据库。
【讨论】:
【参考方案2】:我首先使用了表格,然后在(如果)有原因时重构为一个成熟的 msg 队列 - 如果您的设计合理,这将是微不足道的。
最大的好处是 a.) 它更容易,(b. 它是一个更好的审计跟踪,因为您有其他表可以连接,c.) 如果您非常了解数据库工具,它们比Message Queue 工具,d.)在您的应用程序已经存在的上下文中设置测试/开发环境通常会更容易一些(如果同样熟悉的话)。
哦,而且 e。)也许对于您和其他人来说,它不是另一个需要学习、安装、配置、管理和支持的产品。
IMPE,它同样可靠、可断开连接,如果需要更高的可扩展性,您可以进行转换。
【讨论】:
【参考方案3】:数据永久存储在表中。我见过很多 java (jms) 应用程序在途中因未捕获的异常或其他错误而丢失或消失消息。
哪个 JMS 实现? Sun 销售不会丢失消息的可靠队列。也许您刚刚购买了符合 JMS 标准的俗气产品。 IBM 的 MQ 非常可靠,并且有 JMS 库可以访问它。
队列往往会被填满。相反,数据库存储实际上是无限的。
嗯...如果您的队列已满,听起来好像有什么东西坏了。如果您的应用程序崩溃,那不是一件好事,队列与此关系不大。如果您购买了一个非常糟糕的 JMS 实现,我可以看到您可能对它不满意的地方。这是一个竞争激烈的市场。寻找更好的队列管理器。 Sun 的 JCAPS 有一个非常好的队列管理器,以前是 SeeBeyond 消息队列。
表格很容易访问,而您必须使用深奥的工具从队列中读取。
这不符合我的经验。表是通过这种特殊的“其他语言”(SQL) 访问的,并且要求我了解从表到对象的结构映射以及从 VARCHAR2 到字符串的数据类型映射。此外,我必须使用某种访问层(JDBC 或使用 JDBC 的 ORM)。这看起来非常非常复杂。通过 MessageConsumers 和 MessageProducers 使用简单的发送和接收访问队列。
【讨论】:
过于努力地抹黑发帖者(显然是大量的)个人经历。并非每个人都对问题和选项有您明显的高度熟悉。 这就是 SO 的重点:低熟悉度的人向高熟悉度的人学习。这就是为什么像这样的答案应该投赞成票,而不是反对票。 @doofledordfer:不要抹黑——他们的经验是真实的——但它可能是基于廉价的实现。问题是:是什么导致了他们的观点?【参考方案4】:听起来您遇到的问题似乎不是消息传递所固有的,而是消息传递系统实现不善的产物。构建消息系统是否比构建数据库系统更难?是的,如果您所做的只是构建数据库系统。
由于未捕获的异常而丢失消息?这几乎不是消息队列的错。您使用的应用程序设计不佳。他们在处理完成之前从队列中删除消息。他们没有使用交易或日记。 当数据库存储“几乎无限”时,消息队列已满?你说的好像管理磁盘空间是数据库不需要的东西。消息队列服务器需要管理,就像数据库服务器一样。 从队列中读取的神秘仪器?也许如果您发现异步方法深奥。也许如果您发现序列化和反序列化深奥。 (至少,这些是我在学习消息传递时发现的深奥的东西。就像许多看似深奥的技术一样,一旦你了解它们,它们实际上就很平凡,而理解它们是经验丰富的开发人员教育的重要组成部分。)使其优于数据库的消息传递方面:
异步处理。消息队列在新消息到达时通知等待进程。要在数据库中完成此功能,等待进程必须轮询数据库。 关注点分离。 沟通渠道与消息内容的实现细节分离。只有发送者和接收者需要知道给定消息中数据流的格式。 容错。。当服务器之间的连接断断续续时,消息传递可以发挥作用。消息队列可以在本地存储消息,并且仅在连接有效时将它们转发到远程服务器。 系统集成。 至少在 Windows 世界中,消息传递是内置在操作系统中的。它使用操作系统的安全模型,通过操作系统的工具等进行管理。如果你不需要这些东西,你可能不需要消息传递。
下面是一个简单的消息传递应用程序示例:我正在构建一个系统,其中分布在多个网络中的用户正在输入相当复杂的交易集,这些交易集用于生成打印输出。输出生成的计算成本很高,并且不是其工作流程的一部分;即,用户不在乎何时生成输出,只关心它。
因此,我们将事务序列化为消息并将其放入队列中。在服务器上运行的进程从队列中获取消息,生成输出,并将输出存储在映像系统中。
如果我们使用数据库作为我们的消息存储,我们必须想出一个模式来存储目前只有发送方和接收方关心的事务格式,我们需要确保网络上的每个工作站网络有到数据库服务器的永久持久连接,我们没有能力在多个服务器之间分配这个事务负载,我们的输出服务器每天必须查询数据库数千次,等待是否有新的作业要处理.
【讨论】:
【参考方案5】:每次都跳动这句话完全取决于您的要求。当然,它不会每次都击败所有人。
如果您正在构建一个已经在使用数据库的单一系统,那么您没有非常高的性能吞吐量要求,并且您不必与任何其他团队或系统进行通信,那么您可能是对的。
对于简单、低吞吐量、主要是单线程的东西,数据库是消息队列的完美替代品。
消息队列的亮点在于何时
您需要一个高性能、高并发和可扩展的负载平衡器,这样您就可以在许多服务器/进程上同时处理每秒数万条消息(使用数据库表,您可以幸运地每秒处理数百条消息,并且多线程处理非常困难,因为一个进程往往会锁定消息队列表) 您需要使用不同的数据库在不同的系统之间进行通信(因此不必将系统数据库的写入权限分发给不同团队中的其他人等)对于具有单个数据库、团队和相当适中的性能要求的简单系统 - 一定要使用数据库。为工作使用正确的工具等。
但是,消息队列在大型组织中大放异彩,那里有许多需要相互通信的系统(因此您不希望业务数据库成为故障的中心点或版本地狱的地方)或当您有高性能要求时。
就性能而言,消息队列总是胜过数据库表——因为消息队列是专门为这项工作而设计的,并且不依赖于悲观表锁(这是数据库实现队列所必需的——执行负载均衡)和good message queues will perform eager loading of messages to queues to avoid the network overhead of a database。
同样 - 您永远不会使用数据库在 Web 服务器上对 HTTP 请求进行负载平衡 - 因为它太慢了 - 如果您对负载平衡器有很高的性能要求,您也不会使用数据库.
【讨论】:
这个答案比任何其他形式的答案都要好。以上是关于消息系统中针对表的队列[关闭]的主要内容,如果未能解决你的问题,请参考以下文章