Конец ядовитым сообщениям!


Никогда больше не теряйте сообщения и сократите время устранения неполадок с помощью событий с трассировкой в реальном времени Memphis.dev

Вам когда-нибудь звонили посреди ночи и говорили: «Инфраструктура выглядит нормально, но какой-то сервис не потребляет данные / сообщения доставляются повторно. Пожалуйста, разберитесь с этим».

Повторно доставленные сообщения также называются «отравленными сообщениями».

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

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

В RabbitMQ, например, очереди кворума отслеживают количество неудачных попыток доставки и отображают его в заголовке «x-delivery-count», который включается в любое повторно доставленное сообщение. Можно установить предел доставки для очереди с помощью аргумента политики, delivery-limit. Если сообщение было возвращено большее количество раз, чем установлено лимитом, оно будет отброшено или отправлено в мертвую очередь (если настроен DLX).

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

В RabbitMQ наиболее распространенным и простым решением является включение DLX (dead-lettered queue), но на этом все не заканчивается.

Восстановление отравленного сообщения — это только первая часть, разработчик также должен понять, что вызывает такое поведение, и устранить проблему.


Решения

Хотя существует классическое решение — зафиксировать/признать сообщение как можно скорее, это не лучший вариант для случаев, когда требуется, чтобы сообщения подтверждались только после завершения обработки.

Другие подходы —

Как обрабатывать непризнанные сообщения в RabbitMQ

  1. Включите DLX
  2. Настройте DLX
  3. Разместите ключ маршрутизации
  4. Создайте выделенный потребитель, указанный на DLX
  5. Потреблять непринятые сообщения
  6. Исправьте код/события

Как обрабатывать непринятые сообщения в Apache Kafka

Не существует готового способа повторной доставки/восстановления таких сообщений.

  1. Убедитесь, что в коде есть журналы, отслеживающие исключения, и экспорт в pagerduty/datadog/new relic/etc….

  2. Если срок хранения сообщения слишком мал, оно исчезнет до того, как разработчик получит возможность его отладить. В большинстве случаев сообщение не будет уникальным и может потеряться, но в других, таких как транзакции/атомарные запросы, это так. Чтобы смягчить это, необходимо сделать обертку, обеспечивающую эту функциональность. Отличным примером такой обертки, обеспечивающей такую возможность и даже больше, является GreyHound https://github.com/wix/greyhound от Wix. Определенно стоит взглянуть.

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


Непризнанные сообщения в Memphis.dev

Когда мы начали уточнять наш подход, понимать потребности, проверять опыт и создавать ценность, которую он принесет нашим пользователям, три ключевые задачи руководили нашим процессом — это

  1. Точка входа пользователя в проблему.
  2. Быстрое понимание проблемного потребителя и первопричины проблемы.
  3. Код исправляется. Разработчик должен отладить исправление с помощью аналогичного сообщения, чтобы убедиться, что оно работает.

1 — Определите триггер

В брокере Memphis на уровне SDK мы используем параметр под названием «maxMsgDeliveries».
При достижении этого порога брокер не будет повторно отправлять сообщение «failed-to-ack» одной и той же группе потребителей.

2 — Уведомление

  • Брокер Memphis фиксирует событие пересечения «maxMsgDeliveries = 2» для каждой станции, для каждой группы потребителей.
  • Сохраняет время_отправки и полезную нагрузку повторно доставленного сообщения в файловом хранилище Memphis в течение 3 часов.
  • Пометьте сообщение как отравленное определенным потребителем.
  • Создайте предупреждение.

3 — Определите группу потребителей, которая не подтвердила сообщение.

Вместо того чтобы просматривать журналы и многочисленные группы потребителей, мы хотели сузить поиск до минимума, поэтому простое нажатие на «трассировку в реальном времени» приведет к появлению экрана с графиком, показывающим КУ, которые прошли порог повторной доставки.

4 — Исправление и отладка

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

Непризнанное сообщение будет извлекаться из внутренней БД Memphis, попадать в специальную станцию для каждой станции, для каждого CG, и только по запросу. Затем оно будет передано непризнанному CG — БЕЗ ИЗМЕНЕНИЯ КОДА, с использованием того же самого уже настроенного emit.

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

Все еще в процессе разработки, но если вам интересно — sandbox.memphis.dev

Автор этой статьи — Авраам Нееман

Оцените статью
devanswers.ru
Добавить комментарий