Порядок сообщений, DLQ, graceful shutdown, spike нагрузки — на каждый вопрос есть минимум два рабочих ответа

Витя Михайлов, Backend Lead Garage Eight, и Женя Янченко, руководитель разработки и автор тг-канала @jane_yanchenko, разобрали 5 вопросов про брокеры со стороны RabbitMQ и Kafka соответственно.
Вопрос 1. Как вы обеспечиваете порядок сообщений, когда это критично для бизнес-логики? Например, событие «покупка товара» не должно обработаться раньше события «счет пополнен».
RabbitMQ:
Только один консьюмер на очередь.
Ack( ) только после завершения бизнес-логики.
Если используешь nack — убедись, что тип очереди не quorum: он меняет логику requeue.
Publish только строго с confirmation mode, и обработчиком connection.blocked, чтобы FlowControl не испортил нам порядок (выключить его нельзя).
— Витя
Kafka:
Kafka обеспечивает порядок в рамках одной партиции. Партиция определяется по ключу: все сообщения с одинаковым ключом попадут в одну партицию.
Например, если выбрать ключом ID заказа, все события по нему попадут в одну партицию.
Нюансы:
определенные настройки ретраев продюсера могут привести к нарушению порядка
изменение числа партиций может сломать прежнее распределение
— Женя
Вопрос 2. Что делать с сообщением, которое консьюмер не может обработать уже 10 раз подряд? Стратегии retry, DLQ, алертинг — как это устроено на практике.
RabbitMQ:
Сначала понять: можно ли вообще обработать сообщение? Битый JSON или некорректные данные — повторные попытки бессмысленны. Отправляем в DLX или дропаем с записью в лог.
Если обработать можно — два варианта:
1) Ретраить бесконечно (осторожно: poison message handling). Нужен мониторинг и rate limit на повторы.
2) Отбросить в DLQ, но тогда теряем порядок обработки.— Витя
Kafka:
Заводим отдельный топик — Dead Letter Queue (DLQ).
1) Пробуем обработать сообщение. Успех — коммитим оффсет.
2) Ошибка — ретраим N раз. Помогает при временных сбоях (БД не ответила), но не при битом сообщении.
3) Попытки исчерпаны — отправляем в DLQ в исходном виде + пишем в лог.
4) Сообщения в DLQ анализируются вручную.
Вопрос 3. Как обеспечить обратную совместимость схемы сообщений при обновлении сервиса? Продюсер и консьюмер деплоятся независимо — как не сломать друг друга.
RabbitMQ:
Нельзя. Ломать. Обратную совместимость.
Миграция работает так: в какой-то момент поддерживаешь обе схемы параллельно, затем выключаешь старую. Хороший пример с тремя реальными сценариями миграции — официальный гайд RabbitMQ по переходу с classic на quorum queues.
— Витя
Kafka:
Схема сообщений в топике — публичный контракт, как в REST API. Изменения проектируем так, чтобы обе версии какое-то время работали параллельно.
Безопасно:
Добавить необязательное поле, добавить поле с дефолтом, перестать использовать поле (но не удалять).Опасно:
Переименовать, изменить тип, удалить обязательное поле, поменять смысл.Для валидации схем — Schema Registry (особенно при Avro или Protobuf).— Женя
Ответы от ребят на еще два вопроса ждут в нашем канале.
















