Apache Apollo

Apache Apollo представляет собой брокер сообщений, построенный на базе ActiveMQ и ориентированный на высокую производительность, гибкую маршрутизацию и поддержку нескольких протоколов, включая STOMP. В контексте STOMP.js он выступает серверной точкой обмена сообщениями, обеспечивающей доставку событий между клиентами через очереди и топики.

STOMP.js функционирует как клиентская библиотека, реализующая протокол STOMP поверх WebSocket или других транспортов. Apache Apollo в этой связке играет роль посредника, принимающего, маршрутизирующего и доставляющего сообщения между подписчиками и отправителями.


Протокол STOMP и модель взаимодействия с брокером

STOMP (Simple/Streaming Text Oriented Messaging Protocol) использует текстовые кадры для обмена сообщениями между клиентом и брокером. Apache Apollo интерпретирует эти кадры и преобразует их в операции с очередями и топиками.

Основные операции взаимодействия:

  • CONNECT — установка соединения с брокером
  • SEND — отправка сообщения в очередь или топик
  • SUBSCRIBE — подписка на канал доставки
  • UNSUBSCRIBE — отмена подписки
  • ACK — подтверждение получения сообщения

STOMP.js формирует эти кадры автоматически, а Apollo выполняет их обработку на серверной стороне.


Подключение STOMP.js к Apache Apollo

Взаимодействие осуществляется через WebSocket-эндпоинт, предоставляемый брокером. Apollo обычно публикует STOMP-интерфейс по адресу вида /stomp или /ws.

Пример подключения:

import { Client } from '@stomp/stompjs';

const client = new Client({
  brokerURL: 'ws://localhost:61614/stomp',
  reconnectDelay: 5000,
  heartbeatIncoming: 4000,
  heartbeatOutgoing: 4000,
});

client.onConn ect = (frame) => {
  console.log('Соединение установлено', frame);
};

client.activate();

Apache Apollo обрабатывает handshake WebSocket и переводит соединение в STOMP-сессию.


Очереди и топики в Apache Apollo

Модель сообщений в Apollo делится на два базовых типа:

Очереди (Queues) Сообщение доставляется только одному потребителю. После обработки оно удаляется из очереди.

Топики (Topics) Сообщение рассылается всем подписчикам одновременно.

STOMP.js использует адресацию через destination:

  • /queue/orders
  • /topic/notifications

Пример подписки:

client.subscribe('/topic/notifications', (message) => {
  const payload = JSON.parse(message.body);
  console.log('Получено сообщение:', payload);
});

Apache Apollo сопоставляет destination с внутренними маршрутами доставки.


Формирование и отправка сообщений

Отправка данных осуществляется через кадр SEND. STOMP.js абстрагирует этот процесс:

client.publish({
  destination: '/queue/orders',
  body: JSON.stringify({
    orderId: 123,
    status: 'created'
  })
});

На стороне Apache Apollo сообщение попадает в очередь /queue/orders, после чего распределяется среди потребителей.


Механизмы подтверждения доставки

Apache Apollo поддерживает режимы подтверждения сообщений:

  • auto — автоматическое подтверждение при получении
  • client — подтверждение вручную через ACK
  • client-individual — подтверждение каждого сообщения отдельно

Пример ручного подтверждения:

client.subscribe('/queue/tasks', (message) => {
  const data = JSON.parse(message.body);

  processTask(data);

  message.ack();
}, { ack: 'client' });

В этом режиме Apollo ожидает явного подтверждения, прежде чем удалить сообщение из очереди.


Персистентность сообщений

Apache Apollo может сохранять сообщения на диск, обеспечивая их восстановление после перезапуска брокера. Это критично для систем, где потеря сообщений недопустима.

Поведение зависит от конфигурации очереди:

  • volatile — сообщения хранятся в памяти
  • persistent — сообщения записываются в хранилище

STOMP.js на клиентской стороне не управляет этим напрямую, но может устанавливать заголовки:

client.publish({
  destination: '/queue/orders',
  body: JSON.stringify({ id: 1 }),
  headers: {
    persistent: 'true'
  }
});

Управление потоками и backpressure

Apache Apollo поддерживает контроль нагрузки через ограничение prefetch — количество сообщений, отправляемых клиенту до подтверждения.

STOMP.js может косвенно влиять на это через настройки подписки:

client.subscribe('/queue/jobs', handler, {
  'prefetch-count': 10
});

Это позволяет контролировать поток сообщений и снижать риск перегрузки клиента.


Heartbeat и поддержание соединения

Для предотвращения разрыва соединения Apollo и STOMP.js используют heartbeat-механизм.

const client = new Client({
  brokerURL: 'ws://localhost:61614/stomp',
  heartbeatIncoming: 10000,
  heartbeatOutgoing: 10000,
});

Apache Apollo отслеживает активность канала и закрывает неактивные сессии при отсутствии heartbeat-сигналов.


Обработка ошибок и переподключение

При нестабильном соединении STOMP.js автоматически инициирует переподключение при включённой настройке:

reconnectDelay: 5000

Apache Apollo при этом сохраняет состояние очередей и подписок (при persistent-сессиях), что позволяет восстановить поток сообщений после восстановления соединения.


Безопасность и авторизация

Apache Apollo поддерживает аутентификацию пользователей при подключении STOMP-клиента.

Заголовки CONNECT могут содержать учетные данные:

client.connectHeaders = {
  login: 'user',
  passcode: 'password'
};

Брокер проверяет права доступа к destination, позволяя или запрещая операции SEND и SUBSCRIBE.


Маршрутизация и виртуальные хосты

Apache Apollo поддерживает сложную маршрутизацию сообщений между виртуальными хостами и пространствами имён.

Примеры логических пространств:

  • /queue/inventory
  • /topic/events/system

STOMP.js работает с этими путями как с абстрактными адресами, не зная о внутренней топологии брокера.


Логика обработки сообщений в связке STOMP.js и Apollo

Процесс передачи данных включает последовательность этапов:

  1. Установка WebSocket-соединения
  2. STOMP CONNECT handshake
  3. Регистрация подписок SUBSCRIBE
  4. Отправка SEND сообщений
  5. Маршрутизация внутри Apache Apollo
  6. Доставка сообщения подписчику
  7. ACK (при необходимости)
  8. Удаление или сохранение сообщения

Каждый этап контролируется либо клиентом (STOMP.js), либо брокером (Apache Apollo), в зависимости от конфигурации.


Оптимизация производительности

Apache Apollo поддерживает буферизацию и batch-доставку сообщений, что снижает нагрузку на сеть. STOMP.js в свою очередь может группировать отправку сообщений на клиенте.

Ключевые факторы производительности:

  • размер очередей
  • prefetch
  • частота heartbeat
  • тип подписки (durable / non-durable)
  • режим подтверждения

Интеграция с распределёнными системами

Apache Apollo может работать как часть более крупной системы обмена сообщениями, включая мосты между брокерами. STOMP.js в этом случае остаётся конечной точкой взаимодействия, не изменяя свою модель работы.

Сообщения могут:

  • пересылаться между брокерами
  • агрегироваться в централизованных очередях
  • маршрутизироваться по правилам фильтрации

Работа с временными очередями

STOMP.js поддерживает создание временных destination, которые существуют только в рамках сессии. Apache Apollo удаляет такие очереди после завершения соединения.

Пример:

client.subscribe('/temp-queue/session123', handler);

Такие очереди применяются для RPC-подобных сценариев.


Поведение при масштабировании

Apache Apollo способен распределять нагрузку между несколькими потребителями одной очереди. STOMP.js при этом остаётся статeless-клиентом, что позволяет горизонтально масштабировать фронтенд без изменений логики обмена сообщениями.

Балансировка происходит на уровне брокера, а не клиента.