我有一个基于Spring JMS的DLQ消息监听器。它从我在HornetQ中配置的DLQ中提取消息,然后将其记录到文件中,这样我就可以看到哪些类型的消息无法传递。我的DLQ处理程序成功处理了我的DLQ上的消息,但HornetQ会定期记录此警告:
2015-02-24 14:02:23,372 WARN (Thread-16 (HornetQ-server-HornetQServerImpl::serverUUID=fcc18714-ad5e-11e4-8b50-2febab581439-739562537)) [org.hornetq.core.server] HQ222015: Internal error! Delivery logic has identified a non delivery and still handled a consumer!
为什么会发生这种情况?如何修复我的HornetQ配置以防止此警告?
DLQ&到期队列设置为:
<address-settings>
<address-setting match="#">
<dead-letter-address>jms.queue.DLQ</dead-letter-address>
<max-delivery-attempts>3</max-delivery-attempts>
<redelivery-delay>5000</redelivery-delay>
<expiry-address>jms.queue.ExpiryQueue</expiry-address>
<last-value-queue>true</last-value-queue>
<max-size-bytes>100000</max-size-bytes>
<page-size-bytes>20000</page-size-bytes>
<redistribution-delay>0</redistribution-delay>
<send-to-dla-on-no-route>true</send-to-dla-on-no-route>
<address-full-policy>PAGE</address-full-policy>
</address-setting>
</address-settings>
这是记录WARN的HornetQ Java Source。它在这个类中: org.hornetq.core.server.impl.QueueImpl.java
这是我的JmsListenerContainerFactory。我尝试了所有缓存设置,HornetQ WARNing仍然出现在所有缓存设置上。
/**
* Returns a factory that has NO JTA configured, so message processing
* will not be transactional
*
* To use, you must set @JmsListener(connectionFactory="nonJtaJmsListenerContainerFactory")
*
* @return
*/
@Bean(name="nonJtaJmsListenerContainerFactory")
public DefaultJmsListenerContainerFactory nonJtaJmsListenerContainerFactory() {
DefaultJmsListenerContainerFactory factory =
new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setDestinationResolver(destinationResolver);
String cacheLevelName = environment.getProperty("application.jms.defaultlistenercontainer.cache-level", "CACHE_SESSION");
factory.setCacheLevelName(cacheLevelName);
String concurrencyRange = environment.getProperty("application.jms.defaultlistenercontainer.concurrency-range", "1-10");
factory.setConcurrency(concurrencyRange);
return factory;
}
这是我的DLQ和过期队列处理程序。它使用Spring的@JmsListener注释。
/**
* Handles both DLQ and Expired messages
*
*/
@Component
public class DLQHandler {
private Log log = LogFactory.getLog(getClass());
private AtomicLong dqlCounter = new AtomicLong();
private AtomicLong expiryCounter = new AtomicLong();
/**
*
*/
public DLQHandler() {
}
@JmsListener(destination="/queue/DLQ",
containerFactory="nonJtaJmsListenerContainerFactory",
concurrency="1-50")
public void handleDLQMessage(Message message) {
if (log.isTraceEnabled()) {
log.trace("DLQ Msg Handled ["+dqlCounter.getAndIncrement()+"] >> "+message);
}
}
@JmsListener(destination="/queue/ExpiryQueue",
containerFactory="nonJtaJmsListenerContainerFactory")
public void handleExpiryMessage(Message message) {
if (log.isTraceEnabled()) {
log.trace("Expired Msg Handled ["+expiryCounter.getAndIncrement()+"] >> "+message);
}
}
}