Java Message Service
Java Message Service (JMS) — это стандарт Java Platform, Enterprise Edition (Java EE), определяющий набор интерфейсов (API) для асинхронного обмена сообщениями между приложениями или компонентами распределённой системы. JMS обеспечивает надёжную, транзакционную и независимую от платформы передачу данных в виде сообщений, позволяя развязывать отправителя и получателя во времени и пространстве. Стандарт был разработан компанией Sun Microsystems (ныне Oracle Corporation) и впервые опубликован в 1998 году.
История
Первая версия спецификации JMS (1.0) была выпущена в 1998 году компанией Sun Microsystems. Целью создания стандарта было унификация подходов к обмену сообщениями в Java-приложениях, которые до этого использовали проприетарные протоколы и API различных брокеров сообщений (например, IBM MQSeries, TIBCO Rendezvous). JMS позволил разработчикам писать код, не зависящий от конкретной реализации брокера, при условии соблюдения спецификации.
В 2002 году вышла версия JMS 1.1, которая упростила модель программирования, объединив два ранее раздельных API (для очередей и топиков) в единый унифицированный интерфейс. Эта версия оставалась основной на протяжении многих лет.
В 2013 году, в составе спецификации Java EE 7, была выпущена версия JMS 2.0. Она привнесла упрощённый API (легковесный интерфейс), поддержку внедрения зависимостей (CDI) и новые возможности, такие как отложенная отправка сообщений и асинхронная отправка без блокировки.
Архитектура и модель обмена
JMS основана на модели обмена сообщениями, которая включает несколько ключевых компонентов.
Основные компоненты
- JMS-провайдер (брокер сообщений) — это система, реализующая спецификацию JMS и обеспечивающая маршрутизацию, хранение и доставку сообщений. Примерами являются Apache ActiveMQ, RabbitMQ (с плагином JMS), IBM MQ, Oracle WebLogic JMS.
- JMS-клиент — это Java-приложение, которое отправляет или получает сообщения. Клиент может быть как производителем (sender/publisher), так и потребителем (receiver/subscriber).
- Сообщение (Message) — это единица данных, передаваемая между клиентами. Состоит из заголовка (header), свойств (properties) и тела (body).
- Административные объекты (Administered Objects) — это объекты, создаваемые администратором JMS-провайдера и используемые клиентами для подключения. К ним относятся:
ConnectionFactory— объект, используемый клиентом для создания соединения с провайдером.Destination— объект, представляющий собой точку назначения сообщения (очередь или топик).
Модели обмена сообщениями
JMS поддерживает две основные модели обмена, которые называются доменами сообщений (messaging domains):
- Модель «точка-точка» (Point-to-Point, P2P). Основана на использовании очередей (Queue). Производитель отправляет сообщение в очередь. Сообщение может быть получено только одним потребителем (из группы, подписанной на эту очередь). После успешного получения сообщение удаляется из очереди. Эта модель гарантирует, что каждое сообщение будет обработано ровно один раз.
- Модель «издатель-подписчик» (Publish-Subscribe, Pub/Sub). Основана на использовании топиков (Topic). Издатель отправляет сообщение в топик. Сообщение доставляется всем активным подписчикам, которые подписаны на этот топик. Существует два типа подписок:
- Неустойчивая подписка (Non-durable subscription) — подписчик получает сообщения только в момент, когда он активен и подключён к брокеру. Сообщения, отправленные в его отсутствие, теряются.
- Устойчивая подписка (Durable subscription) — брокер сохраняет сообщения для подписчика, даже если он отключён. При повторном подключении подписчик получает все сообщения, отправленные за время его отсутствия.
Структура сообщения
Сообщение JMS состоит из трёх частей:
- Заголовок (Header) — содержит обязательные поля, такие как идентификатор сообщения (
JMSMessageID), отметка времени (JMSTimestamp), тип сообщения (JMSType), режим доставки (persistent/non-persistent), приоритет и время жизни (expiration). - Свойства (Properties) — необязательные поля, которые могут быть использованы для фильтрации сообщений на стороне брокера (селекторы сообщений). Свойства могут быть трёх типов: прикладные (application-specific), стандартные (JMS-defined) и специфичные для провайдера (provider-specific).
- Тело (Body) — содержит полезную нагрузку сообщения. JMS определяет несколько типов тел:
TextMessage— строка (например, XML или JSON).ObjectMessage— сериализованный Java-объект.BytesMessage— массив байтов.MapMessage— набор пар «ключ-значение».StreamMessage— поток примитивных типов данных.
API и программирование
JMS API предоставляет два набора интерфейсов: классический (Classic API) и упрощённый (Simplified API), введённый в версии 2.0.
Классический API (JMS 1.1)
Работа с классическим API включает следующие шаги:
- Создание
ConnectionFactoryиDestination(обычно через JNDI lookup). - Создание
ConnectionизConnectionFactory. - Создание
SessionизConnection(с указанием режима транзакций и подтверждения). - Создание
MessageProducerилиMessageConsumerизSessionиDestination. - Отправка сообщений через
MessageProducerили приём черезMessageConsumer. - Закрытие ресурсов в обратном порядке.
Упрощённый API (JMS 2.0)
Упрощённый API использует аннотации и внедрение зависимостей (CDI) для сокращения объёма кода. Вместо создания Session и Connection вручную, разработчик может напрямую внедрить JMSContext (который объединяет Connection и Session). Также появились методы-однострочники для отправки и приёма сообщений, например, context.createProducer().send(destination, message).
Режимы подтверждения и транзакции
JMS поддерживает несколько режимов подтверждения получения сообщений (acknowledgement modes):
AUTO_ACKNOWLEDGE— сообщение автоматически подтверждается после того, как клиент его получил.CLIENT_ACKNOWLEDGE— клиент должен явно вызвать методmessage.acknowledge()для подтверждения.DUPS_OK_ACKNOWLEDGE— ленивое подтверждение, допускающее повторную доставку сообщений в случае сбоя.
Кроме того, JMS поддерживает транзакции. В рамках транзакционной сессии все отправленные и полученные сообщения либо подтверждаются (commit), либо откатываются (rollback) как единое целое.
Применение
JMS широко используется в корпоративных приложениях для решения следующих задач:
- Интеграция приложений (EAI) — обеспечение обмена данными между разнородными системами (ERP, CRM, базы данных) без прямого связывания.
- Асинхронная обработка — разгрузка веб-серверов путём передачи длительных задач (например, генерация отчётов, отправка email) в фоновые очереди.
- Событийно-ориентированная архитектура (EDA) — уведомление компонентов системы о наступлении определённых событий (например, изменение статуса заказа) через топики.
- Надёжная доставка — гарантия доставки сообщений даже при временных сбоях сети или отключении потребителя (persistent messages).
- Балансировка нагрузки — распределение задач между несколькими потребителями с помощью очередей.
Критика и ограничения
Несмотря на широкое распространение, JMS имеет ряд критических замечаний:
- Зависимость от Java — JMS является Java-специфичным стандартом, что ограничивает его использование в мультиязычных средах без дополнительных шлюзов.
- Сложность администрирования — управление административными объектами (ConnectionFactory, Destination) часто требует ручной настройки на стороне провайдера.
- Отсутствие стандартизации маршрутизации — JMS не определяет механизмы сложной маршрутизации, трансформации сообщений или управления потоками (flow control), что вынуждает разработчиков использовать проприетарные расширения провайдеров.
- Конкуренция с современными протоколами — появление таких протоколов, как AMQP (Advanced Message Queuing Protocol) и MQTT (Message Queuing Telemetry Transport), которые являются открытыми и не зависят от языка программирования, привело к снижению популярности JMS в некоторых областях, особенно в Интернете вещей (IoT) и микросервисной архитектуре.
Сравнение с другими технологиями
| Характеристика | JMS | AMQP | MQTT |
|---|---|---|---|
| Языковая зависимость | Java | Независимый | Независимый |
| Модели обмена | P2P, Pub/Sub | P2P, Pub/Sub, Request/Reply | Pub/Sub |
| Уровень надёжности | Высокий (persistent, transactions) | Высокий (configurable) | Средний (QoS 0,1,2) |
| Производительность | Средняя | Высокая | Очень высокая |
| Область применения | Корпоративные Java-приложения | Универсальная интеграция | IoT, мобильные устройства |
Интересные факты
- Спецификация JMS 1.1 была настолько стабильной, что многие брокеры сообщений (например, ActiveMQ) поддерживали её в течение более 15 лет без существенных изменений.
- Несмотря на появление JMS 2.0, многие крупные проекты (например, Apache Camel, Spring JMS) по-прежнему поддерживают оба API.
- JMS является одним из немногих спецификаций Java EE, которые получили широкое распространение за пределами серверов приложений, благодаря использованию в лёгких брокерах, таких как ActiveMQ Artemis.
Источники
- Спецификация JMS 2.0 (JSR 343), Oracle Corporation, 2013.
- Спецификация JMS 1.1, Sun Microsystems, 2002.
- Java Message Service, 2nd Edition, Mark Richards, Richard Monson-Haefel, O'Reilly Media, 2009.
- Документация Apache ActiveMQ Classic.
- Документация RabbitMQ по плагину JMS.
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →