Как понять обмен сообщениями "синхронный" и "асинхронный" в 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.