HornetQ:为什么使用DLQ处理程序导致此HQ222015 WARN?

时间:2015-02-24 21:34:23

标签: hornetq spring-jms

我有一个基于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

enter image description here

这是我的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);
        }
    }

}

0 个答案:

没有答案