RabbitMQ - перемещать сообщения перед удалением очереди - PullRequest
2 голосов
/ 12 февраля 2020

Использование RabbitMQ 3.7.16, spring-amqp 2.2.3.RELEASE.

Несколько клиентов публикуют sh сообщений для обмена DataExchange topi c на нашем сервере RabbitMQ с использованием уникального ключа маршрутизации. При отсутствии каких-либо привязок, обмен перенаправит все сообщения на data.queue.generic через AE.

Когда определенный клиент (идентификатор клиента 1 и 2 на диаграмме) публикует много сообщения, чтобы масштабировать потребление их сообщений независимо от других клиентов, мы начинаем потребителей и назначаем им обработку только их идентификатора клиента. Чтобы достичь этого, каждый клиент-потребитель определяет новую очередь и связывает ее с обменом topi c с помощью ключа маршрутизации events.<clientID>.

Таким образом, масштабирование покрыто и работает хорошо.

Теперь, когда частота сообщений для этого клиента снижается, мы хотели бы также уменьшить количество его потребителей, вплоть до удаления всех из них. Намерение состоит в том, чтобы все эти сообщения были направлены в GenericExchange, где есть пул общих c потребителей, которые заботятся о них.

Проблема заключается в том, что если я delete data.queue.2 (чтобы удалить привязку, которая приведет к перенаправлению новых сообщений на GenericExchange), все ожидающие сообщения будут потеряны.

Вот упрощенное представление архитектуры:

Dead letter messages from expired/deleted queue

Было бы приемлемым решением позволить истечению срока действия сообщений с TTL в очереди клиента, а затем переслать их в общий обмен c, но затем Мне также нужно остановить обмен topi c от маршрутизации новых сообщений в эту «умирающую» очередь.

Итак, какие опции у меня есть, чтобы остановить обмен topi c от маршрутизации сообщения в очередь клиента, где теперь нет подключенного к нему потребителя?

Или изучить другой путь - как перевести сообщения в виде удаленных писем в удаленную / просроченную очередь?

1 Ответ

1 голос
/ 12 февраля 2020

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

С этого момента все новые сообщения для клиента будут go через альтернативный обмен, ваш "generi c exchange", обрабатываться вашими generi c потребителями.

Что касается сообщений, оставшихся в очереди клиентов, вы можете использовать лопату, чтобы отправить их обратно на обмен topi c, чтобы они были направлены на обмен generi c.

Это основано по предположению альтернативный обмен является внутренним. Если он не внутренний, вы можете нацелиться на него непосредственно с помощью лопаты.

Как обсуждалось с Богданом, другой вариант решения этой проблемы, при котором гарантируется отсутствие потери сообщений, - это выполнить несколько шагов:

  • убрать привязку между заданной c очередью и обменом
  • имеет некоторые логи c, чтобы оставшиеся сообщения были либо использованы, либо перенаправлены в общую c очередь
    • если удаление привязки происходит до разъединения потребителя (ей), отключите последнего потребителя только после того, как очередь пуста
    • , если удаление привязки происходит после последнего разъединения потребителя, укажите TTL для сообщений с альтернативным обмениваться как generi c exchange
  • в зависимости от ранее выбранных опций, иметь некоторый механизм очистки для удаления старых пустых очередей
...