Как отклонять сообщения после перелопативания из одной очереди в другую?

С помощью Spring и RabbitMQ я создал два обмена темами x и dlx и две очереди q и dlq. q привязан к x, а dlq к dlx. dlx настроен как обмен недоставленными сообщениями для q.

Когда сообщение в q отклоняется (с удалением из очереди), оно успешно отправляется на dlx, а затем на dlq.

Теперь я использую плагин лопатки, чтобы переместить сообщения с мертвыми буквами в dlq обратно в q. Это работает успешно, если на этот раз сообщения обрабатываются успешно (подтверждение).

Но если одно из этих перелопатленных сообщений inq снова отклоняется, оно отбрасывается без уведомления. Я ожидаю, что его снова отправят в DLX dlx. Я что-то неправильно настроил или неправильно понял концепцию DLX или лопат?


person Datz    schedule 30.04.2018    source источник


Ответы (2)


Я подозреваю, что вы улавливаете вкус этого ...

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

... потому что вы копаете. См. Обмен недоставленными письмами.

Вместо этого настройте DLQ с TTL и конфигурацией недоставленных сообщений, которая заставляет просроченные сообщения перенаправляться обратно в исходную очередь. Таким образом, заголовок x-death получает две записи - 1 для отклонений из исходной очереди и 1 для истечения срока из DLQ.

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

person Gary Russell    schedule 30.04.2018
comment
Спасибо за это объяснение. Я читал цитату раньше, но не уверен, применима ли она здесь. В нем говорится if there was no rejections in the entire cycle. В моем случае сообщение отклоняется один раз. Я попробую использовать специальный ключ маршрутизации мертвой буквы. Посмотрим, что будет потом ... - person Datz; 01.05.2018
comment
Да - я просто размышлял - однако я много раз успешно использовал технику TTL. - person Gary Russell; 01.05.2018
comment
Я мог решить эту проблему с помощью ключа маршрутизации недоставленных сообщений x-dead-letter-routing-key. (TTL не подходит для моего случая использования.) - person Datz; 15.05.2018

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

https://www.rabbitmq.com/tutorials/amqp-concepts.html#exchange-default

Обмен по умолчанию - это прямой обмен без имени (пустая строка), предварительно объявленного брокером. У него есть одно специальное свойство, которое делает его очень полезным для простых приложений: каждая создаваемая очередь автоматически привязывается к ней с ключом маршрутизации, который совпадает с именем очереди.

Основываясь на приведенном выше примере, я предполагаю, что у вас есть следующие настройки:

  • q аргументы - x-dead-letter-exchange = dlx
  • q привязка: test_message
  • dlq привязка: test_message

Итак, если вы отправляете сообщение на x с ключом маршрутизации test_message, оно маршрутизируется следующим образом:

  1. Появляется в q
  2. Потребитель в q получает сообщение, отправляет Nack, который отправляет dlx с ключом маршрутизации test_message
  3. dlx dlq настроен на привязку к test_message ключу маршрутизации, поэтому сообщение появляется в dlq

Теперь, когда вы используете плагин лопаты из dlq, чтобы переместить все сообщения в q следующим образом:

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

Затем это отправляет сообщение exchange = '' и routing_key = 'q'. Также из https://www.rabbitmq.com/dlx.html#using-optional-queue-arguments, в нем говорится:

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

Итак, вот что происходит:

  1. Сообщение появляется в q с routing_key = q
  2. Поскольку x-dead-letter-routing-key не настроен, он не отправляет письма на dlx с routing_key q
  3. Нет привязки к q в dlx, сообщение сброшено

2 возможных исправления:

  1. Добавьте еще одну привязку от dlq к routing_key = q
  2. Вручную настройте x-dead-letter-routing-key в очереди q, чтобы всегда отправлять на один и тот же ключ маршрутизации в мертвом письме
person phillipuniverse    schedule 03.08.2020