JMS 队列已满

2022-09-04 02:32:51

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

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


答案 1

对于任何异步消息传递,您都必须处理“快速生产者/慢速消费者”问题。有许多方法可以解决这个问题。

  1. 添加使用者。使用 WebSphere MQ,您可以根据深度触发队列。一些商店使用它来随着队列深度的增长添加新的使用者实例。然后,随着队列深度开始下降,额外的消费者就会消失。通过这种方式,可以使消费者自动扩展以适应不断变化的负载。其他代理通常具有类似的功能。
  2. 使队列和底层文件系统变得非常大。此方法尝试完全吸收队列中工作负荷的峰值。毕竟,这是队列最初设计的目的。问题是,它不能很好地扩展,您必须分配磁盘,99%的时间几乎是空的。
  3. 使旧邮件过期。如果消息设置了过期时间,则可以将其清理。某些 JMS 代理将自动执行此操作,而在其他代理上,您可能需要浏览队列才能删除过期的消息。这样做的问题是,并非所有邮件都会失去其业务价值并符合到期条件。大多数即发即弃消息(审核日志等)都属于此类别。
  4. 限制生产者。当队列填满时,没有任何东西可以向它放置新消息。在 WebSphere MQ 中,生成应用程序随后会收到一个返回代码,指示队列已满。如果应用程序区分致命错误和暂时性错误,它可以停止并重试。

成功实现其中任何一个的关键是允许系统提供应用程序将响应的“软”错误。例如,许多商店会在首次获得 QFULL 条件时提高队列的 MAXDEPTH 参数。如果队列深度超过底层文件系统的大小,则结果是文件系统将填充并影响整个节点,而不是影响单个队列的“软”错误。您最好调整系统,以便队列在文件系统填满之前达到MAXDEPTH,然后再检测应用程序或其他进程,以以某种方式对完整队列做出反应。

但无论你做什么,上面的选项#4都是强制性的。无论您分配了多少磁盘,部署了多少使用者实例,或者消息过期的速度有多快,您的使用者总是有可能跟不上消息生产。发生这种情况时,你的生产者应用应该限制,或者发出警报,然后停止或执行挂起或死亡以外的任何操作。异步消息传递仅在您用完空间来排队消息之前是异步的。之后,你的应用是同步的,必须优雅地处理这种情况,即使这意味着(优雅地)关闭自己的应用。


答案 2

确定!

http://download.oracle.com/docs/cd/E17802_01/products/products/jms/javadoc-102a/index.html 完全按照您的要求。Message#setJMSExpiration(long)


推荐