我试图为我的JMS消息创建一个临时使用者(我使用ActiveMQ)
它看起来像这样:
jmsTemplate.browse(
q.getName(),
new BrowserCallback<Integer>() {
@Override
public Integer doInJms(Session session, QueueBrowser browser) throws JMSException {
Queue destination = session.createQueue(q.getName());
Enumeration<?> enum1 = browser.getEnumeration();
while (enum1.hasMoreElements()) {
ActiveMQObjectMessage msg = (ActiveMQObjectMessage) enum1.nextElement();
MessageConsumer consumer = session.createConsumer(destination);
Message m = consumer.receiveNoWait();
handle(m);
m.acknowledge();
此临时使用者应处理所有未能使用的消息。 问题是我在spring-messaging.xml中定义的原始2-3个消费者不断尝试通过重新传递配置来处理失败的事件和重试(重新传递延迟设置为3秒,并且重新传输的数量是无限的)
这位消费者应该处理这些消息,但实际上是在挨饿(根本不会收到这些消息,因此
Message m = consumer.receiveNoWait();
始终返回null。
这是我的豆子:
<bean id="redeliveryPolicy" class="org.apache.activemq.RedeliveryPolicy">
<property name="queue" value="*" />
<property name="initialRedeliveryDelay" value="0" />
<property name="redeliveryDelay" value="2000" />
<property name="maximumRedeliveries" value="-1" />
</bean>
<!-- A JmsTemplate instance that uses the cached connection and destination -->
<bean id="redeliveryJmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="redeliveryCachingConnectionFactory" />
<property name="messageConverter" ref="eventConverter" />
<property name="sessionTransacted" value="true" />
</bean>
p.s当我将p:sessionCacheSize的配置更改为1:
时 <bean id="redeliveryCachingConnectionFactory"
class="org.springframework.jms.connection.CachingConnectionFactory"
p:targetConnectionFactory-ref="redeliveryConnectionFactory"
p:sessionCacheSize="1" />
它有效,但我想使用缓存。
有什么想法吗?
答案 0 :(得分:0)
您假设队列浏览器正在返回耗材消息。浏览消息就像是浏览完成时的快照。它将包括分配给预取的任何消息,或者当您再次访问它时,它可能已被消耗。此外,您不会等待分配消息,因此您不断回到消息行。
我建议允许将消息移动到DLQ,然后允许此Adhoc消费者使用它。否则,您正在与其他消费者竞争消息。
如果您真的死于使用DLQ,则可以使用JMS selectors基于JMSRedelivered
标头为true,等待时间更长。您仍然会与其他消费者竞争,但会在某个时候收到消息。