Почему потребитель остановился, если сообщение не содержит условия селектора сообщений? - PullRequest
0 голосов
/ 18 апреля 2019

Я недавно работаю с JMS, и у меня есть такой вопрос. Я должен получить сообщение 1) Все сообщения 2) Только там, где type = 'LIQUID'. Я создал двух потребителей

Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        Queue queue = session.createQueue(QUEUE_FOR_RECEIVED);
        QueueBrowser queueBrowser = session.createBrowser(queue);
        Enumeration enumeration = queueBrowser.getEnumeration();
        MessageConsumer consumer = session.createConsumer(queue);
        MessageConsumer liquidConsumer = session.createConsumer(queue, "type = 'LIQUID'");

Первый получил все сообщения, второй только с type = 'LIQUID'. Но второй потребитель просто остановил приложение, если сообщение не содержит type='LIQUID'

while (enumeration.hasMoreElements()) {
            ObjectMessage ss = (ObjectMessage) consumer.receive();
            System.out.println(ss.getObject());
            ObjectMessage msg = (ObjectMessage) liquidConsumer.receive(); // here consumer stopped if message doesn't contain type ='LIQUID'
            System.out.println(msg.getObject());
            enumeration.nextElement();
        }

Как это можно улучшить?

1 Ответ

1 голос
/ 18 апреля 2019

Причина, по которой приложение остановлено, заключается в том, что javax.jms.MessageConsumer.receive() является блокирующим вызовом. Другими словами, он будет блокировать дальнейшее выполнение, пока не будет возвращен результат. Если в очереди нет сообщений, соответствующих селектору, то вызов javax.jms.MessageConsumer.receive() будет блокироваться бесконечно. Это ожидаемое, задокументированное поведение.

Если вы не хотите блокировать здесь бесконечно, вы можете:

  1. Получение сообщений асинхронно (например, с использованием реализации javax.jms.MessageListener)
  2. Используйте javax.jms.MessageConsumer.receive(int) и передайте тайм-аут на receive, чтобы звонок возвращался, если по истечении указанного времени не было получено ни одного сообщения.
  3. Используйте javax.jms.MessageConsumer.receiveNoWait(), который будет пытаться получить следующее соответствующее сообщение, и если подходящее сообщение не будет немедленно доступно, он вернется.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...