Как понять обмен сообщениями "синхронный" и "асинхронный" в JMS?

После прочтения некоторого документа JMS я полностью озадачен фразой synchronous и asynchronouns.

Смотрите эту страницу: http://docs.oracle.com/cd/E19798-01/821-1841/bncdq/index.html

Синхронный

Вы используете метод приема для синхронного использования сообщения. Вы можете использовать этот метод в любое время после вызова метода start:

connection.start();
Message m = consumer.receive();
connection.start();
Message m = consumer.receive(1000); // time out after a second

Чтобы асинхронно использовать сообщение, вы используете прослушиватель сообщений, описанный в следующем разделе.

Асинхронный

Слушатели сообщений JMS Слушатель сообщений - это объект, который действует как асинхронный обработчик событий для сообщений. Этот объект реализует интерфейс MessageListener, который содержит один метод, onMessage. В методе onMessage вы определяете действия, которые необходимо предпринять, когда приходит сообщение.

Вы регистрируете прослушиватель сообщений с помощью определенного MessageConsumer с помощью метода setMessageListener. Например, если вы определяете класс с именем Listener, который реализует интерфейс MessageListener, вы можете зарегистрировать прослушиватель сообщений следующим образом:

Listener myListener = new Listener();
consumer.setMessageListener(myListener);

У меня есть два вопроса:

  • Как я понял, природа JMS асинхронна. Продюсер публикует сообщения в очередь/тему, ему не нужно ждать потребителя. Это асинхронное поведение. Как это может быть "синхронно"?

  • Если "mesageListener" асинхронен, но в моем тесте с spring -jms я нашел, что он всегда работает в потоке. Это означает, что если я пишу Thread.sleep(2000) в onMessage, он должен ждать 2 секунды перед обработкой следующего сообщения. Это "асинхронно"?

Ответ 1

Если вы так поняли, consumer.receive() использует модель pull: вы читаете из очереди и блокируете ее до тех пор, пока она не появится, или не истечет какой-то тайм-аут.

Использование прослушивателя использует push-модель: вы регистрируете прослушиватель и, когда приходит сообщение, слушатель вызывается в отдельном потоке.

Все выполняется в потоке в Java, а вызов прослушивателя не является исключением. Независимо от того, обрабатывает ли обработка сообщений слушателя обработку других сообщений в очереди, зависит от того, сколько потоков посвящено обработке сообщений. Если вы настроите Spring использовать пул из 5 потоков для обработки асинхронных сообщений, то 5 слушателей смогут обрабатывать сообщения параллельно.

Ответ 2

Как я понимаю это:

асинхронный - MessageListener: Используйте это на сервере, который слушает очередь. Когда сообщение поступит, немедленно обратитесь к нему. Сервер продолжает слушать эту очередь.

synchronous - consumer.receive(1000): Используйте это в клиентских приложениях, которые время от времени должны проверять, предназначено ли для этого клиента сообщение. Пример: опрос каждые 60 секунд. Это приведет к немедленному открытию соединения с сервером. 1000 миллисекунд будут поддерживать это соединение открытым. Если сообщение достигнет этих 1000 миллисекунд, тогда сообщение будет потреблено и соединение будет закрыто.

Ответ 3

Вы смотрите на это от конца до конца: от издателя до потребителя. Да, это асинхронная доставка от издателя к потребителю независимо от потребителя Sync/Async. Однако Sync/Async в вашем вопросе предназначен только для потребителей, то есть от брокера JMS (например: ApacheMQ) до потребителя. Как отмечали другие, пользователи Sync последовательно выводят сообщения от брокера и ждут сообщений. Асинхронные потребители регистрируют обратный вызов, когда на него нажимаются сообщения (onMessage). Потребители Async могут заниматься другими вещами, в то время как эти сообщения доставляются им асинхронно от брокера JMS.