Как JMS Receive работает внутри?

#java #jms #message-queue #messaging

#java #jms #очередь сообщений #обмен сообщениями

Вопрос:

Я изучал различные коммуникационные технологии / архитектуры / шаблоны / реализации (читай: модные словечки), включая веб-сервисы (WCF, Axis2), ESBs, SOA, и хотел узнать больше о JMS в отношении обмена сообщениями.

Концептуально JMS звучит просто. Я полагаю, что это промежуточный брокер, который управляет сообщениями от издателей и направляет их соответствующим подписчикам. Это делается путем постановки сообщений в очередь по мере их публикации и удаления их из очереди по мере их получения.

Вопрос 1: Правильно ли мое базовое понимание JMS?

Одна из вещей, которая меня беспокоит при чтении о технологиях, — это когда определенный уровень (намеренный или непреднамеренный) махания рукой делается в отношении функции.

Исходя из моего базового понимания, поставщик JMS должен быть запущен, чтобы отправлять или получать сообщения. Мое предположение о публикации заключается в том, что поставщик JMS просто ожидает, пока сообщение не будет опубликовано, затем сохраняет его в очереди (с поддержкой памяти или базы данных, в зависимости от реализации). Однако я не совсем уверен, как работает receive.

Вопрос 2. Блокируется ли receive (обычно), если сообщения недоступны?

Вопрос 2b: Если да, то как достигается блокировка? Клиент постоянно опрашивает сообщения? Сервер просто не отвечает, пока не будет опубликовано сообщение (как это работает без тайм-аута?) Инициирует ли провайдер вызов получателю?

Вопрос 2c: Если нет, то как обеспечить своевременное получение сообщений без ущерба для производительности?

Основное описание, похоже, ориентировано на одного поставщика JMS, чтобы гарантировать, что сообщения, управляемые централизованно, не будут потеряны. Я вижу, что масштабирование является проблемой.

Вопрос 3: Как JMS масштабируется?

При масштабировании я вижу сложности, связанные с обеспечением доставки одного сообщения всем соответствующим подписчикам, независимо от того, какой физический сервер получает сообщение.

Вопрос 3b: Как реализация JMS обеспечивает надежную доставку в масштабируемой среде?

Пожалуйста, обратите внимание, что, хотя эти вопросы связаны с JMS, они, вероятно, применимы к любой инфраструктуре обмена сообщениями. Я приветствую ответы, относящиеся как к JMS, так и к тем, которые являются более общими или даже специфичными для другой технологии.

Комментарии:

1. если вы хотите углубиться, horneq имеет открытый исходный код и предоставляет реализацию jms. Инструкции по получению исходного кода здесь . Возможно, вы также захотите прочитать разделы «Архитектура» и «Концепции» в документах , это может помочь вам несколько сократить объем ваших вопросов.

Ответ №1:

Я пытаюсь ответить на несколько вопросов, основанных на моем опыте работы с JMS.

Ответ 1:- JMS — это Java Message Service API; он предоставляет клиентам Java единый интерфейс для доступа к платформе обмена сообщениями. Под JMS API находится поставщик обмена сообщениями, совместимый с JMS, например WebSphere MQ provider. JMS поддерживает передачу полезной нагрузки по любому протоколу обмена сообщениями адресатам, а именно. Очередь и тема. Это основы JMS.

Как работает receive? Спецификация JMS предоставляет два важных класса:- MessageConsumer и MessageListener . MessageConsumer класс позволяет клиенту JMS синхронно получать сообщения JMS, вызывая любой из его receive() методов. Этот вызов будет блокировать поток до тех пор, пока не будет получено сообщение. В противном случае асинхронный прием может быть выполнен путем регистрации объекта MessageListener с MessageConsumer помощью. Именно JMSProvider узнает, что сообщение прибыло в его локальное место назначения, и его задачей является доставка сообщений либо в поток-получатель опрашиваемого сообщения, либо в поток-слушатель зарегистрированных сообщений, не проводящий опроса.

Ответ 2: —
MessageConsumer API имеет два варианта receive: receive() и receive(long timeout) . Последний вариант позволяет MessageConsumer блокировать поток до тех пор, пока сообщение не поступит в течение определенного периода ожидания, иначе время ожидания истечет.

Различные платформы обмена сообщениями могут реализовывать функцию блокировки по-разному. Поскольку объекты JMS являются объектами, администрируемыми JNDI, и прокси-объекты, специфичные для поставщика, возвращаются клиенту JMS, это означает, что клиент не знает о том, как происходит блокировка в фоновом режиме. Конкретная платформа обмена сообщениями может выбрать опрос потока-получателя сообщения после определенного периода времени. В качестве альтернативы, он может выбрать блокировку до отправки уведомления.

Я не уверен, ищете ли вы ответ на конкретную платформу обмена сообщениями, совместимую с JMS?

Ответ 3: — Я предполагаю, что под масштабированием JMS вы подразумеваете возможность иметь много издателей / подписчиков, много адресатов на нескольких физических машинах. Масштабирование JMS требует поддержки базового поставщика обмена сообщениями для поддержки некоторого вида кластеризации / сбоя. Как таковая спецификация JMS не поддерживает масштабируемость. Поправьте меня, если я ошибаюсь в этом? Например, я работал над WebSphere MQ, совместимым с JMS, который обеспечивает поддержку кластеризации.

Комментарии:

1. Я понимаю, что JMS — это всего лишь спецификация, поэтому я в основном прочитал ваш ответ как «это зависит от реализации» (что вполне приемлемо). Я надеялся получить более подробную техническую информацию об аспекте блокировки, связанном с опросом / etc. Более общий вопрос может заключаться в том, как асинхронная архитектура обмена сообщениями масштабируется без негативного влияния на производительность (при условии, что все подписчики либо проводят опрос, открывают соединения и блокируют, либо ожидают широковещательной рассылки).

Ответ №2:

Вопрос 1: Правильно ли мое базовое понимание JMS?

Давайте сначала разберемся с терминологией. Вы не можете сказать JMS Provider must be running , потому что provider — это объект, который создал сервер JMS, и именно сервер JMS должен быть запущен. Следовательно, когда мы говорим JMS, мы имеем в виду набор API (более технически — интерфейсов), которые реализуют поставщики. Итак, в основном провайдеры пишут свою собственную реализацию JMS. Например, Active MQ is a JMS server это обеспечивается Apache(provider)

Мое предположение о публикации заключается в том, что поставщик JMS просто ожидает, пока сообщение не будет опубликовано, затем сохраняет его в очереди (с поддержкой памяти или базы данных, в зависимости от реализации).

В какой-то степени верно. Существуют разные модели, которым следуют. Сервер JMS поддерживает сокет открытым. Всякий раз, когда клиент-отправитель должен отправить сообщение, он просто открывает соединение с сокетом и отправляет сообщение. Поведение receive совершенно другое. У вас есть pull и push. В режиме push сервер отправляет сообщения клиенту-получателю в режиме реального времени, как только он получает сообщение. Это также называется асинхронным режимом. В модели извлечения клиент-получатель отправляет запрос на сервер для получения сообщений (синхронный режим).

Блокируется ли прием (обычно), если сообщения недоступны?

Как я упоминал в предыдущем пункте, это будет зависеть от используемой вами модели. Приемник будет заблокирован в модели извлечения (синхронный прием). Также это происходит в сеансовом потоке, а не в основном потоке.

Если да, то как достигается блокировка? Клиент постоянно опрашивает сообщения?

Да, клиент будет постоянно опрашивать в случае модели извлечения. Обычно существует тайм-аут, после которого клиент будет завершен.

Если нет, то как обеспечить своевременное получение сообщений без ущерба для производительности?

Используйте асинхронный режим. Вам просто нужно зарегистрировать MessageListener, и он получит сообщение о том, что оно переопределено onMessage (сообщение msg), когда есть доступность сообщений на сервере.

Вопрос 3: Как JMS масштабируется?

Это действительно вопрос, о котором должны беспокоиться провайдеры. Когда вы говорите, что сообщение получено всеми подписчиками, вы имеете в виду модель связи PUBSUB (другой является PTP). В PUBSUB сообщение, отправленное в тему, будет доставлено всем подписчикам, подписанным на эту тему.

Вопрос 3b: Как реализация JMS обеспечивает надежную доставку в масштабируемой среде?

Надежность? Не всегда. Опять же, это зависит от варианта использования. У вас могут быть как постоянные, так и непостоянные сообщения. В случае постоянных сообщений сообщения сохраняются в базе данных (файле или других), и их доставка обеспечивается. В случае непостоянных сообщений такой гарантии нет. Сбой сервера может привести к потере сообщения.

Комментарии:

1. Ваши ответы в основном просто увековечивают проблему, с которой я сталкиваюсь в целом (т. Е. размахивание руками). Наличие прослушивателя, который получает сообщение, описывает / что / происходит, но не объясняет, как сообщения доставляются асинхронно эффективным способом. Вы упомянули блокировку с помощью модели извлечения, но как реализован асинхронный провайдер? Да, масштабируемость и надежность, очевидно, являются проблемами, о которых должен беспокоиться поставщик. Но как они обычно работают?

2. В асинхронной модели получатель зарегистрирует MessageListener . Это делается в потоке сеанса . После регистрации сеанса поток может продолжить его обработку. Когда сообщение доступно в очереди или теме, сообщение отправляется клиенту. Библиотека на стороне клиента вызовет функцию обратного вызова onMessage() MessageListener с полученным сообщением в SessionThread, где у вас есть своя логика обработки сообщений.

3. Я все еще ищу более подробную информацию — например, учтите, что ваш клиент находится на одном сервере, ваш поставщик JMS — это масштабируемая система (т. Е. Более одного сервера). С точки зрения сети, к чему подключается клиент, как доставляются ответы в обратном направлении. Я думаю, вы пытаетесь сказать, что сервер инициирует обратное соединение с клиентом для доставки сообщения. Что произойдет, если клиент все же отключен? Опять же, меня беспокоит надежность (гарантированная доставка, постоянные сообщения) и производительность (время доставки).

Ответ №3:

JMS поддерживает прием сообщений синхронным методом (прием с таймаутом, блокирующим ваш поток, и без него) или с обратным вызовом, управляемым событиями (асинхронный прослушиватель сообщений)).

Вы можете решить, какой метод лучше соответствует вашим потребностям, но вам также может потребоваться взглянуть на фактическую реализацию. Например, некоторые реализации JMS выполняют сетевое переключение для receive() и, следовательно, лучше использовать с таймаутом или с прослушивателем.

С поведением потока прослушивателя сообщений и приостановкой приема сообщений не так легко управлять, как с блокирующим вызовом receive. Обычно большая часть контроля достигается за счет наличия собственного пула блокирующих вызовов receive() с тайм-аутами, отправляемых вашим работникам.

Ответ №4:

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

Очередь: только один клиент получит сообщение. Для масштабирования у вас может быть, например, 10 клиентов, подключенных к одной очереди, но только один из них получит определенное сообщение. Если ни один клиент не подключен, сообщение будет оставаться в очереди до тех пор, пока кто-нибудь не подключится или время ожидания сообщения не истечет.

Тема: все клиенты получат копию каждого сообщения. Обычно используется в сценарии подписчика, где многие конечные точки потенциально заинтересованы в каждом сообщении. Постоянный подписчик может даже отключаться на некоторое время; сообщение будет храниться до тех пор, пока подписчик снова не подключится или время ожидания сообщения не истечет. Если ни один клиент не подключен и нет постоянных подписчиков, сообщение будет удалено.

Ответ №5:

В JMS существует два типа доменов обмена сообщениями.

  1. Домен обмена сообщениями Point-To-Point(PTP)
  2. Домен обмена сообщениями между издателем и подписчиком

В модели PTP одно сообщение доставляется только одному получателю. Здесь Queue используется как Mсущность управляемого Mпрограммного обеспечения iddleware (MOM).

Очередь отвечает за хранение сообщения до тех пор, пока получатель не будет готов.

В модели PTP нет временной зависимости между отправителем и получателем.

введите описание изображения здесь


В модели Pub / Sub всем подписчикам доставляется одно сообщение. Это похоже на широковещательную передачу. Здесь Topic используется как промежуточное программное обеспечение, ориентированное на сообщения, которое отвечает за хранение и доставку сообщений.

В модели PTP существует временная зависимость между издателем и подписчиком.

введите описание изображения здесь


Модель программирования JMS

введите описание изображения здесь

Источник


Message Dрасколотый Bean (MDB)

  • MDB — это компонент, содержащий бизнес-логику. Но он вызывается путем передачи сообщения. Итак, это похоже на JMS Receiver.
  • MDB асинхронно получает сообщение и обрабатывает его.
  • MDB получает сообщение из очереди или темы.
  • MDB подобен сеансовому компоненту без состояния, который инкапсулирует бизнес-логику и не поддерживает состояние компонента.

введите описание изображения здесь