> Как используется RabbitMQ в проектах (Go)
Уровень: senior · Роль: backend · Язык: Go · Категория: Технические вопросы
Компании: InDrive
Стек: Go, Java
> Пример ответа
Короткий ответ
В Go и Java проектах RabbitMQ обычно применяют для асинхронной доставки сообщений между сервисами, разгрузки синхронных вызовов и реализации паттернов work queue, pub/sub, routing и RPC. На senior-уровне важны идемпотентность, подтверждения, dead letter queues, back pressure и порядок обработки. Выбор между RabbitMQ и Kafka определяется trade-off: маршрутизация и низкая задержка против лог-ориентированной потоковой обработки.
Подробное объяснение
RabbitMQ - это message broker с моделью AMQP, где producer публикует сообщение в exchange, exchange маршрутизирует его в queue по routing key или заголовкам, а consumer забирает из queue. В Go типично используют библиотеку amqp091-go, в Java - Spring AMQP или официальный Java client. Основные сценарии: разгрузка HTTP-запросов через фоновую обработку, интеграция микросервисов без жёсткой связности, распределение задач между воркерами, событийные уведомления и отложенные задачи через TTL и dead letter exchange. На senior-уровне обсуждают гарантии доставки: at-least-once достигается через publisher confirms и manual ack, exactly-once в общем случае не гарантируется и требует идемпотентного consumer. Важны prefetch, чтобы не перегружать consumer, и обработка poison messages через DLQ. Также учитывают порядок сообщений: он сохраняется в пределах одной queue и одного consumer, но нарушается при конкурентной обработке. Для RPC используют reply-to и correlation-id, хотя это увеличивает связанность. В высоконагруженных системах применяют quorum queues для репликации и устойчивости, а также шардирование по routing key. Сравнение с Kafka: RabbitMQ лучше для сложной маршрутизации и низкой задержки отдельных сообщений, Kafka - для потоковой обработки и replay.
На практике
В Go consumer запускают в отдельной горутине, настраивают channel с prefetch, обрабатывают сообщения с context timeout и подтверждают ack только после успешной записи в БД или отправки следующего события. При ошибке делают nack с requeue=false, чтобы сообщение ушло в DLQ. В Java аналогично настраивают SimpleMessageListenerContainer с concurrency и manual ack. Для идемпотентности хранят message-id в Redis или в таблице с уникальным индексом. Для отложенных задач используют per-message TTL и dead letter exchange. Мониторинг строят на RabbitMQ management plugin и метриках queue depth, unacked messages, publish rate. При деплое учитывают, что consumer должен быть готов к переподключению и повторной доставке.
Пример кода
GOpackage mainimport ("context""log""time"amqp "github.com/rabbitmq/amqp091-go")func main() {conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")if err != nil {log.Fatal(err)}defer conn.Close()ch, err := conn.Channel()if err != nil {log.Fatal(err)}defer ch.Close()q, err := ch.QueueDeclare("tasks", true, false, false, false, nil)if err != nil {log.Fatal(err)}err = ch.Qos(10, 0, false)if err != nil {log.Fatal(err)}msgs, err := ch.Consume(q.Name, "", false, false, false, false, nil)if err != nil {log.Fatal(err)}for msg := range msgs {ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)if err := process(ctx, msg.Body); err != nil {_ = msg.Nack(false, false)} else {_ = msg.Ack(false)}cancel()}}func process(ctx context.Context, body []byte) error {return nil}
Как отвечать на собеседовании
Сначала назовите 2-3 ключевых сценария: асинхронная обработка, интеграция сервисов, распределение задач. Затем объясните модель exchange-queue-binding и гарантии доставки. Упомяните идемпотентность, DLQ, prefetch и publisher confirms. Сравните с Kafka по критериям маршрутизации, порядка и replay. Приведите пример из практики с Go или Java и покажите, как обрабатываете ошибки и повторные доставки. В конце отметьте мониторинг и эксплуатационные аспекты.
Что проверяет интервьюер
Понимание модели AMQP и топологии exchange. Умение выбирать гарантии доставки и обрабатывать повторные сообщения. Знание идемпотентности и DLQ. Опыт настройки prefetch и back pressure. Понимание ограничений порядка и exactly-once. Способность сравнить RabbitMQ с Kafka и обосновать выбор. Практические навыки в Go или Java: подключение, ack, reconnect, мониторинг.
Типичные ошибки
Использовать auto-ack и терять сообщения при падении consumer. Игнорировать идемпотентность при at-least-once. Ставить бесконечный requeue и получать poison message loop. Не настраивать prefetch и перегружать consumer. Ожидать exactly-once без транзакций и идемпотентности. Путать порядок сообщений в разных queue. Забывать про publisher confirms и терять сообщения на стороне producer. Выбирать RabbitMQ для потоковой обработки больших объёмов без оценки trade-off.
> Похожие задачи по Go
Есть ли у вас вопросы по процессу собеседования или этапам
Как у тебя сейчас с поиском работы
Что делать если в Kafka мало места при большом объеме сообщений
Как работает оператор break в цикле и какой будет вывод
> Похожие задачи по backend
Есть ли у вас вопросы по процессу собеседования или этапам
Как у тебя сейчас с поиском работы
Что делать если в Kafka мало места при большом объеме сообщений
Как работает оператор break в цикле и какой будет вывод
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью