Сообщения RabbitMQ NACK - PullRequest
       7

Сообщения RabbitMQ NACK

0 голосов
/ 28 января 2019

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

Есть ли способ избежать этого?Можно ли зафиксировать сообщение таким образом, чтобы следующее сообщение точно не было только что захваченным?

Я использую Node.js и amqp.node для связи с RabbitMQ

Ответы [ 3 ]

0 голосов
/ 29 января 2019

Nack является специфичным для RabbitMQ расширением протокола AMQP.Это позволяет потребителю сообщения уведомлять сервер, когда сообщение не было успешно обработано.Я предполагаю, что вы уже достигли этого.

Интересно, что AMQP изначально не считал Nack необходимым.Зачем?Поскольку поведение AMQP, когда потребитель не может обработать сообщение, заключается в том, что потребитель закрывает соединение без ack -ing сообщения .В этой ситуации сообщение автоматически помещается в очередь в том порядке, в котором оно было изначально, и доставляется следующему доступному потребителю с установленным флагом redelivered.

Почему это будет?

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

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

Разница между двумя

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

Что, если я не могу обработать определенное сообщение прямо сейчас , но возможно позже?

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

0 голосов
/ 07 февраля 2019

Как правило, вы можете считать, что если ваш потребитель работает нормально, вы всегда должны подтверждать сообщение, независимо от результата обработки сообщения (как для ошибок, так и для успеха).

Вы можете отклонить / набрать неправильно отформатированное сообщение с помощью Requeue = false, чтобы направить его на обмен недоставленными буквами и выполнить над ним действия (связать очередь и использовать, например, для анализа после вскрытия), или выбрать его для подтверждения.и делать все необходимое (например, отправлять другие сообщения, такие как сообщения BadRequest, ...).

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

Надеюсь, это поможет.

0 голосов
/ 28 января 2019

Вопрос: Мой опыт: в сценарии публикации / подписки, если подписчик получает сообщение, прикрепленное сообщение немедленно помещается в очередь в начале очереди, и это будет следующее сообщение, полученное подписчиком.

Да, это правильно.Когда сообщение ставится в очередь с помощью channel.basicNack, оно будет помещено в свою исходную позицию в своей очереди, если это возможно.Если нет (из-за одновременных доставок и подтверждений от других потребителей, когда несколько потребителей совместно используют очередь), сообщение будет помещено в очередь ближе к заголовку очереди.Источник: https://www.rabbitmq.com/nack.html

Вопрос: есть ли способ избежать этого?Возможно ли зафиксировать сообщение таким образом, что следующее сообщение определенно не будет тем, которое только что было украдено?

Невозможно добиться этого с помощью nack.Одним из способов достижения этого является повторная публикация сообщения обратно в очередь там, где это необходимо.

  • Получите сообщение и немедленно отправьте подтверждение обратно.
  • Обработайте сообщение, еслиуспешно ничего не делать.
  • Если не получилось, не отправлять Nack, а переиздать сообщение обратно в очередь.
...