JMS队列已满

时间:2011-01-26 12:06:08

标签: java jboss jms

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

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

2 个答案:

答案 0 :(得分:14)

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

  1. 添加消费者。使用WebSphere MQ,您可以根据深度触发队列。随着队列深度的增加,一些商店使用它来添加新的消费者实例。然后随着队列深度开始下降,额外的消费者会消失。通过这种方式,消费者可以自动扩展以适应不断变化的负载。其他经纪人通常具有类似的功能。
  2. 使队列和底层文件系统非常大。此方法试图在队列中完全吸收工作负载中的峰值。毕竟这是排队设计的第一步。问题是,它不能很好地扩展,你必须分配磁盘,99%的时间几乎是空的。
  3. 过期旧邮件。如果消息设置了到期日,那么您可以清除它们。某些JMS代理会自动执行此操作,而在其他代理上,您可能需要浏览队列以便删除过期的消息。问题在于并非所有消息都会失去其业务价值并且有资格到期。大多数即发即弃消息(审计日志等)属于此类别。
  4. 节制生产者。当队列填满时,没有任何东西可以向它发送新消息。在WebSphere MQ中,生成应用程序然后接收指示队列已满的返回代码。如果应用程序区分致命错误和瞬态错误,则可以停止并重试。
  5. 成功实施其中任何一项的关键是允许您的系统提供应用程序将响应的“软”错误。例如,许多商店在第一次获得QFULL条件时会提升队列的MAXDEPTH参数。如果队列深度超过基础文件系统的大小,则结果是文件系统填充并影响整个节点,而不是影响单个队列的“软”错误。调整系统要好得多,以便队列在文件系统填充之前很好地达到MAXDEPTH,然后还要检测应用程序或其他进程以某种方式对完整队列作出反应。

    但无论你做什么,上面的选项#4都是强制性的。无论您分配多少磁盘或部署了多少消费者实例,或者消息到达消息的速度有多快,您的消费者总有可能无法跟上消息生成的步伐。当发生这种情况时,您的制作人应用程序应该减速,或者发出警报并停止或做除挂起或死亡之外的任何事情。异步消息传递只是异步,直到你没有空间来排队消息。之后,您的应用程序是同步的,必须优雅地处理这种情况,即使这意味着(优雅地)关闭自己。

答案 1 :(得分:3)

当然!

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