我一直在体验真实生产环境中消息传递系统的优点和缺点,我必须承认,每次任何其他形式的消息传递队列时,组织良好的表或表模式都会跳动,因为:
数据永久存储在表格中.我已经看到很多java(jms)应用程序在未捕获的异常或其他错误的路上丢失或消失了消息.
队列往往会填满.相反,Db存储几乎是无限的.
表格很容易访问,而您必须使用esotic工具从队列中读取.
您对每种方法有何看法?
这句话每次都完全取决于你的要求是什么.当然,它不会每次都为每个人打败.
如果您正在构建一个已经在使用数据库的系统,那么您没有非常高的性能吞吐量要求,并且您不必与任何其他团队或系统进行通信,那么您可能是正确的.
对于简单,低吞吐量,大多数是单线程的东西,数据库是消息队列的完全替代品.
消息队列发光的地方是什么时候
你想要一个高性能,高度并发和可扩展的负载均衡器,这样你就可以在许多服务器/进程间同时处理数万条消息(使用数据库表,你很幸运能够处理几百秒并处理多个线程很难,因为一个进程将倾向于锁定消息队列表)
您需要使用不同的数据库在不同的系统之间进行通信(因此不必向不同团队中的其他人分发对系统数据库的写访问权限)
对于具有单个数据库,团队和相当适度的性能要求的简单系统 - 确保使用数据库.使用正确的工具来完成工作等.
然而,消息队列闪耀的地方是大型组织,其中有许多系统需要相互通信(因此您不希望业务数据库成为故障的中心点或版本地狱的地方)或当您有高性能要求.
在性能方面,消息队列总是会打败数据库表 - 因为消息队列是专门为作业设计的,并且不依赖于悲观表锁(队列的数据库实现所需的 - 进行负载平衡)和好消息队列将执行消息的渴望加载到队列来避免数据库的网络开销.
同样 - 您永远不会使用数据库在Web服务器上对HTTP请求进行负载平衡 - 因为它太慢 - 如果您对负载均衡器有高性能要求,则也不要使用数据库.
我首先使用了表,然后在(如果)有原因的情况下重构成一个成熟的msg队列 - 如果你的设计合理,这是微不足道的.
最大的好处是a.)它更容易,(b.它是一个更好的审计跟踪,因为你有其他表加入,c.)如果你真的很了解数据库工具,它们比Message Queue工具更容易使用,d.)在您的应用程序已经存在的上下文中设置测试/开发环境通常会更容易一些(如果适用相同的熟悉程度).
哦,和e.)对于你和其他人来说,它不是学习,安装,配置,管理和支持的另一种产品.
IMPE,它同样可靠,可断开,如果需要更高的可扩展性,您可以进行转换.
数据永久存储在表格中.我已经看到很多java(jms)应用程序在未捕获的异常或其他错误的路上松散或消失了消息.
哪个JMS实现?Sun销售可靠的队列,不会丢失消息.也许你刚刚购买了一款符合JMS标准的俗气产品.IBM的MQ非常可靠,并且有JMS库可以访问它.
队列往往会填满.相反,Db存储几乎是无限的.
嗯...如果你的队列填满,听起来好像有些东西坏了.如果您的应用程序崩溃,那不是一件好事,而且队列与此无关.如果你购买了一个非常差的JMS实现,我可以看到你可能对它不满意的地方.这是一个竞争激烈的市场.找一个更好的队列管理器.Sun的JCAPS有一个非常好的队列管理器,以前是SeeBeyond消息队列.
表格很容易访问,而您必须使用esotic工具从队列中读取.
这不符合我的经验.通过这种特殊的"其他语言"(SQL)访问表,并要求我了解从表到对象的结构映射以及从VARCHAR2到String的数据类型映射.此外,我必须使用某种访问层(JDBC或使用JDBC的ORM).这似乎非常非常复杂.使用简单的发送和接收通过MessageConsumers和MessageProducers访问队列.
听起来好像您遇到的问题不是消息传递所固有的问题,而是实现效果不佳的消息传递系统的工件.构建消息传递系统比构建数据库系统更困难吗?是的,如果您所做的只是构建数据库系统.
丢失消息到未捕获的异常?这几乎不是消息队列的错误.您正在使用的应用程序设计不良.他们在处理完成之前从队列中删除消息.他们没有使用交易或日记.
数据库存储"几乎无限"时,消息队列会填满吗?你说话就好像管理磁盘空间是数据库不需要的东西.消息队列服务器需要管理,就像数据库服务器一样.
从队列中读取的深奥工具?也许你发现异步方法是深奥的.也许你会发现序列化和反序列化是深奥的.(至少,那些是我在学习信息时发现的东西.就像许多看似深奥的技术一样,一旦你理解它们,它们实际上是非常平凡的,理解它们是经验丰富的开发人员教育的重要组成部分.)
消息传递使其优于数据库的方面:
异步处理. 消息队列在新消息到达时通知等待进程.要在数据库中完成此功能,等待进程必须轮询数据库.
关注点分离. 通信信道与消息内容的实现细节分离.只有发送方和接收方需要知道给定消息中数据流格式的任何信息.
容错性..当服务器之间的连接间歇性时,消息传递可以起作用.消息队列可以在本地存储消息,并在连接生效时仅将消息转发到远程服务器.
系统集成. 至少在Windows世界中,消息传递内置于操作系统中.它使用操作系统的安全模型,通过操作系统的工具等进行管理.
如果您不需要这些东西,则可能不需要消息传递.
这是一个消息传递应用程序的简单示例:我现在正在构建一个系统,其中分布在多个网络中的用户正在进入用于生成打印输出的相当复杂的事务集.输出生成计算成本高,不属于其工作流程; 即,用户不关心何时生成输出,只是它确实如此.
因此,我们将事务序列化为消息并将其放入队列中.在服务器上运行的进程从队列中获取消息,生成输出,并将输出存储在映像系统中.
如果我们使用数据库作为我们的消息存储库,我们必须提出一个模式来存储一个只有发送者和接收者关心的事务格式,我们需要确保网络上的每个工作站都具有永久性与数据库服务器的持久连接,我们没有能力跨多个服务器分配此事务负载,我们的输出服务器必须每天查询数据库数千次,等待查看是否有新的作业要处理.