防止饥饿并确保Spring JMS侦听器池中的最小吞吐量的最佳方法

时间:2012-12-13 23:04:50

标签: jms activemq spring-jms

我有一个JMS侦听器池:

<jms:listener-container connection-factory="jmsConnectionFactory" 
 acknowledge="client" concurrency="10">
    <jms:listener destination="foo1" ref="ref1"/>
    <jms:listener destination="foo2" ref="ref2"/>
    <jms:listener destination="foo3" ref="ref3"/>
    <jms:listener destination="foo4" ref="ref4"/>  // etc...
</jms:listener-container>

我正在寻找一种方法来确保我的某些消息类型不会饿死或阻止所有其他消息类型。示例:我希望至少有M但不超过我的池的N%用于处理foo1消息,即使这样的处理可能会不稳定地停止。

目前,如果我发生这种情况,那么我的池中的所有10个线程将最终专用于foo1消息。 foo {2-4}消息必须等待。我可以通过在我的foo1监听器上执行超时来防止这种饥饿,但后来我的吞吐量目标无法实现。

是否有一些基于配置的简单方法来实现这一目标?我可以同时运行两个JMS侦听器池吗?

或者我最安全的选择是设置两个完全不同的服务器机队,一个专用于foo1消息,另一个专用于foo2-4?

理想情况下,我想做类似以下的事情。但“并发”不是jms的一个属性:listener,只是jms:listener-container:

<jms:listener-container connection-factory="jmsConnectionFactory" 
 acknowledge="client" concurrency="25">
    <jms:listener destination="foo1" ref="ref1" concurrency="10" /> // ensure higher throughput
    <jms:listener destination="foo2" ref="ref2" concurrency="5" />  // don't let foo1 starve me...
    <jms:listener destination="foo3" ref="ref3" concurrency="5" />  // don't let foo1 starve me...
    <jms:listener destination="foo4" ref="ref4" concurrency="5" />  // etc...
</jms:listener-container>

感谢。

1 个答案:

答案 0 :(得分:2)

了解命名空间配置只是简化配置的便利。每个<listener/>元素都会获得自己的侦听器容器,并从<listener-container/>元素“继承”这些属性。

因此,在您的第一个示例中,并发=“10”在所有侦听器中共享 ;每个<listener/>获得10的并发性。

您可以通过声明两个<listener-container/>元素来实现第二个示例,一个是并发10,另一个是5.然后在适当的容器元素中声明每个侦听器。

希望有所帮助。