2012-08-01 2 views
3

Мое приложение работает на Jboss 7.1.1. У меня есть планировщик, который запускается каждую минуту, и вам нужно проверить, есть ли сообщения в DLQ и какие-то обновления в БД.MessageConsumer не принимает сообщений

Я написал потребителю сообщения, который слушает предопределенный пользовательский DLQ. Проблема в том, что я вижу, что есть сообщения в пользовательском DLQ, но consumer.receiveNoWait() всегда возвращает null.

Вот код для создания потребителя:

/*this is running fine and creating the consumer*/ 
public DestinationHandlerImpl(ConnectionFactory connectionFactory, 
    Destination destination, boolean useTransaction, int delMode, 
    boolean isProducer) throws JMSException { 
    connection = connectionFactory.createConnection(); 
    consumer = session.createConsumer(destination); 
} 

Вот код, который потребляет сообщение (работает каждую минуту):

/*this always return null, event when there are messages in the queue*/ 
public <T extends BaseEvent> T recieveMessage() 
     throws JMSException { 

    Message message = consumer.receiveNoWait(); // ----> always return null!!! 

    if (message != null && !(message instanceof ObjectMessage)) { 
     throw new IllegalArgumentException(
       "message object has to be of type ObjectMessage"); 
    } 

    // Extract the object from the message 
    return message == null ? null : (T) ((ObjectMessage) message).getObject(); 

} 

Я использовал режим отладки, и я может видеть, что свойство потребительского назначения установлено в правильную очередь, так что я делаю неправильно?

ответ

9

Нашли это, мне просто нужно было добавить connection.start(), прежде чем начать потреблять.

public <T extends BaseEvent> T recieveMessage() 
    throws JMSException { 

    connection.start(); // --->**added this line** 
    Message message = consumer.receiveNoWait(); 

    if (message != null && !(message instanceof ObjectMessage)) { 
     throw new IllegalArgumentException(
      "message object has to be of type ObjectMessage"); 
    } 

    // Extract the object from the message 
    return message == null ? null : (T) ((ObjectMessage) message).getObject(); 
} 
+0

Я ожидаю, что вы не хотите продолжать вызов 'start()' каждую минуту, но вы должны позвонить ему один раз, когда вы впервые откроете соединение. – seh

+0

Я не забудьте закрыть соединение при каждом запуске планировщика. – Tomer

+0

Могу я спросить, почему? Вы обеспокоены потреблением ресурсов открытого соединения? – seh

0

У меня была эта проблема даже с connection.start()! Рабочее решение для меня:

Использовать receive(long timeout) вместо receiveNoWait();

Обс .: 1000 миллисекунд, поскольку тайм-аут работал нормально в простом тестовом режиме, но, чтобы быть уверенным в производстве, я настраиваю его на 10000 миллисекунд. В моем случае, повторяя сообщения, я останавливаюсь, когда получаю null (больше нет сообщений), и при этом последнем вызове прием (10000) ждет полных 10 секунд (очевидно). Мне пришлось использовать асинхронный подход для смягчения этой проблемы производительности.


Edit: Кроме того, в зависимости от реализации (JBM), он может иметь некоторые сообщения опережающих выборки (предварительно выбрано для потребления), и что делает сообщение недоступным, так как они находятся на доставке статуса.

+1

Кажется, у меня такая же проблема. Мне действительно не нравится звонить получать с тайм-аутом, хотя, потому что это (по определению) состояние гонки. Вы когда-нибудь узнали об этом? – fool4jesus

+0

@ fool4jesus Извините, я больше ничего не нашел в своих исследованиях по этому делу. На самом деле, это действительно отлично работало для меня. – falsarella

Смежные вопросы