ApacheMQ Artemis хранит сообщения без маршрутов
Я использую Artemis 2.6.2
только с STOMP и следующим созвездием:
Маклер:
- В broker.xml нет настроенных очередей, все создается автоматически.
Сервер:
- ПОДПИСАТЬСЯ на пункт назначения
TaskResponse
без селектора / фильтра - ОТПРАВИТЬ в пункт назначения
TaskRequest
с заголовком clientId = ID (идентификатор клиента, к которому сервер будет обращаться)
Клиент 123:
- ПОДПИСАТЬСЯ на пункт назначения
TaskRequest
с селектором clientId = 123 - ОТПРАВИТЬ в пункт назначения
TaskResponse
с заголовком clientId = 123
Когда я смотрю на Artemis Console
происходит следующее:
Сервер и клиент не подключены: адрес или очередь отсутствуют.
Подключение к серверу:
Artemis
создает групповой адресTaskResponse
и многоадресная очередь для этого адреса с пустым фильтромКлиент 123 подключается:
Artemis
создает групповой адресTaskRequest
и многоадресная очередь для этого адреса с фильтром clientId = 123Обмен сообщениями: Сообщения передаются с сервера на клиент и обратно на сервер, как и ожидалось.
Клиент 123 отключается:
Artemis
удаляет групповой адресTaskRequest
и отвечающая за передачу многоадресная очередь с фильтром clientId = 123Сервер отправляет сообщение в TaskRequest для клиента 123: Согласно
STOMP
клиент на сервере сообщение отправлено успешно. На брокере сообщение пропадает.То же самое поведение наоборот: клиент 123 подключен, а сервер - нет: согласно
STOMP
клиент на клиенте 123 сообщение отправлено успешно. На брокере сообщение пропадает.
Я предполагаю, что сообщение отбрасывается, потому что нет маршрута к подписчику. Если я включаю опцию "send-to-dla-on-no-route" в разделе настройки адреса файла broker.xml, то сообщение отправляется непосредственно в очередь недоставленных сообщений.
Знаете ли вы, как сохранить сообщения до повторного подключения абонента?
Приложение 1: Сообщения STOMP
Я использую библиотеку Stomp.Net с примером SelectorsCore, но сводится только к селектору s1. Рабочий процесс немного отличается от того, что я написал выше.
К сожалению, я не нашел пример включения регистрации сообщений STOMP в файл в Artemis. Поэтому я записал пакеты с помощью WireShark, экспортировал их в виде текста и загрузил в Gist StompMessages.txt. Вы можете увидеть различные сообщения STOMP, например, поиск CONNECT, SEND и т. Д.
Решение
Решение было использовать опцию anycastPrefix=/queue/
в acceptor
элемент в broker.xml
заставить очереди печатать ANYCAST
:
<acceptor name="stomp">tcp://0.0.0.0:61613?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=STOMP;useEpoll=true;anycastPrefix=/queue/</acceptor>
1 ответ
То, что вы наблюдаете, - это ожидаемое поведение. Если вы отправляете сообщение на адрес без очередей (или в терминах STOMP - пункт назначения без подписчиков), тогда сообщению некуда будет идти, и оно будет отброшено. Это нормальная семантика pub/sub.
Если вы хотите сохранить сообщения, даже если нет подписчика, вы можете:
- Использовать семантику anycast (т.е. двухточечную) вместо многоадресной. Это обсуждается в документации Артемиды.
- Используйте "надежных" абонентов STOMP, как описано в документации Artemis. Предостережение заключается в том, что подписку по-прежнему необходимо создавать перед отправкой сообщений, и вам также необходимо убедиться, что вы удалили подписку, когда закончили с ней, или она может накапливать сообщения.