【问题标题】:JMS queue is fullJMS 队列已满
【发布时间】:2011-06-15 19:38:35
【问题描述】:

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

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

【问题讨论】:

    标签: java jboss jms


    【解决方案1】:

    当然!

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

    【讨论】:

      【解决方案2】:

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

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

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

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

      【讨论】:

      • 谢谢 T.Rob!你的回答全面而美丽!
      • 很高兴能帮上忙!
      猜你喜欢
      • 2016-10-07
      • 2021-04-29
      • 2012-06-13
      • 1970-01-01
      • 2015-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多