JMS队列已满。

14

我的Java EE应用程序不断向队列发送JMS,但有时JMS消费者应用程序停止接收JMS。这会导致JMS队列非常大,甚至已经满了,从而导致服务器崩溃。 我的服务器是JBoss或Websphere。应用程序服务器是否提供有关删除“超时”JMS消息的策略?

如何处理大型JMS队列的策略是什么?谢谢!

2个回答

15

在任何异步消息传递中,你必须处理“生产者快,消费者慢”的问题,有几种方法可以解决这个问题。

  1. 增加消费者。使用WebSphere MQ,你可以基于深度触发队列。一些商店使用这种方法,在队列深度增长时添加新的消费者实例。然后,当队列深度开始下降时,额外的消费者会自动停止。以这种方式,消费者可以自动扩展以适应不断变化的负载。其他代理商通常具有类似的功能。
  2. 使队列和底层文件系统真正大。这种方法试图完全吸收工作量峰值。毕竟,这就是队列的设计初衷。问题是它不容易扩展,并且您必须分配磁盘,99% 的时间将几乎为空。
  3. 过期旧消息。如果设置了消息过期时间,则可以使它们被清除。一些 JMS 代理会自动执行此操作,而在其他代理上,您可能需要浏览队列以导致过期消息被删除。问题是并非所有消息都会失去其业务价值并变得符合过期要求。大多数 fire-and-forget 消息(审计日志等)属于此类别。
  4. 减缓生产者。当队列填满时,无法将新消息放入其中。在WebSphere MQ中,生产应用程序会收到一个返回码,指示队列已满。如果应用程序区分致命和瞬态错误,则可以停止并重试。

成功实现任何这些方法的关键在于您的系统能够提供应用程序响应的“软”错误。例如,许多商店在第一次收到 QFULL 条件时将队列的 MAXDEPTH 参数提高。如果队列深度超过底层文件系统的大小,则结果是整个节点填充而不是影响单个队列的“软”错误。你最好调整系统以使队列在文件系统填满之前达到 MAXDEPTH,然后还要对应用程序或其他进程进行仪器化以某种方式响应满队列。

但无论你做什么,上述的第四个选项是必须的。不管你分配多少磁盘空间,部署多少消费者实例,或者多快地过期消息,总有可能会出现您的消费者无法跟上消息生产的情况。当发生这种情况时,你的生产者应该降低速度、触发警报并停止发送消息,不要挂起或死机。异步消息仅在排队消息的空间耗尽之前是异步的,此后您的应用程序将变为同步,并且必须优雅地处理这种情况,即使这意味着(优雅地)关闭应用程序。


谢谢T.Rob!你的回答全面而优美! - 卢声远 Shengyuan Lu
很高兴能够提供帮助! - T.Rob

3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接