Сообщения RabbitMQ не отправляются на мертвую букву после первого раза - PullRequest
1 голос
/ 03 августа 2020

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

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

Я предполагаю, что происходит какое-то обнаружение "круговой маршрутизации сообщений", но не могу найти ничего подобного который. Проверка сообщений во второй раз дает все ожидаемые заголовки, поэтому я не уверен, на чем это вообще может быть основано. Мы будем очень благодарны за любые предложения о том, где искать дальше или есть ли у кролика такая вещь!

Если необходимо, наши потребители записываются в python с использованием библиотеки pika для связи.

1 Ответ

1 голос
/ 04 августа 2020

Предполагается, что у вас есть следующие очереди / обмены:

Обмены

  • global_exchange - ваш основной обмен
  • DLX - еще один обмен специально для мертвые письма

Очереди

  • queue - ваша основная очередь в global_exchange. Содержит arguments=x-dead-letter-exchange: 'DLX'
  • queue.dlq - вашу очередь недоставленных сообщений в пределах global_exchange

привязок

  • test_message routing_key, привязанных к queue и queue.dlq

Наконец, я предполагаю, что вы используете плагин лопаты на странице управления queue.dlq, как это, для перемещения сообщений из queue.dlq в queue:

enter image description here

Here is how the routing works when you send a message with test_message as the routing_key to the global_exchange:

  1. Message lands in queue from the binding on test_message
  2. Consumer nack's (nack or reject doesn't matter) the message, thus dead-lettering it
  3. The x-dead-letter-exchange argument sends it to DLX with routing_key= test_message
  4. Because of the queue.dlq binding, that queue receives the message

When you use that particular management panel to shovel messages back into queue, it uses the обмен по умолчанию . Это изменяет ключ маршрутизации . Таким образом, второе получение сообщения имеет ключ маршрутизации, который совпадает с именем очереди, в которую вы загружаетесь.

Поскольку у вас не настроен x-dead-letter-routing-key, сообщение отправляется с мертвой буквы. текущий ключ маршрутизации :

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

Итак по результату лопаты он маршрутизируется так:

  1. Сообщение появляется в queue с routing_key = queue
  2. Так как нет маршрутизации x-dead-letter -key настроен, это мертвые буквы на DLX с routing_key = queue
  3. Без привязки к queue в DLX, сообщение сброшено

Есть 2 возможных обходных пути:

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