RabbitTemplate
RabbitTemplate отправляет сообщения в exchange с routing key. В отличие от Kafka, producer обычно не пишет напрямую в queue: exchange маршрутизирует по bindings.
Для JSON payload настраивают MessageConverter, например Jackson2JsonMessageConverter, и следят за совместимостью формата.
Надёжная отправка: publisher confirms — это асинхронное подтверждение от брокера, что сообщение принято (включается publisher-confirm-type: correlated), а publisher returns возвращает сообщение, которое не попало ни в одну очередь (mandatory=true, когда нет подходящего binding). Без confirms «успешный» convertAndSend лишь значит, что сообщение ушло в сокет, а не что брокер его сохранил, — на сбое сети оно может потеряться молча.
rabbitTemplate.convertAndSend(
"orders.exchange",
"order.paid",
new OrderPaid(orderId)
);
@RabbitListener
@RabbitListener подписывает метод на queue, а listener container управляет consumers, concurrency, prefetch, ack и ошибками.
Prefetch ограничивает число сообщений, которые consumer получил, но ещё не подтвердил. Это важный регулятор fairness и памяти.
@RabbitListener(queues = "billing.order-paid")
void on(OrderPaid event) {
billing.handle(event);
}
Ack, nack и requeue
Режимы подтверждения в Spring AMQP: AUTO (по умолчанию) — контейнер подтверждает сообщение после успешного выполнения listener-а, а при исключении отклоняет; MANUAL — приложение само вызывает basicAck/basicNack; NONE — подтверждение уходит сразу при доставке, как autoAck в клиенте RabbitMQ, и при падении сообщение теряется. Не путайте AUTO в Spring с autoAck брокера: это противоположные по надёжности режимы.
Опасная настройка — бесконечно requeue poison message. Обычно нужны ограниченные retries, backoff и DLQ.
DLQ через DLX
В RabbitMQ dead lettering обычно строится через Dead Letter Exchange: queue настраивают с x-dead-letter-exchange и, при необходимости, x-dead-letter-routing-key.
В DLQ полезно сохранять исходные headers и причину отказа, а также иметь redrive-процесс после исправления ошибки.
Kafka или RabbitMQ в Spring
Spring Kafka удобен для event log, replay и независимых consumer groups. Spring AMQP удобен для work queues, routing, DLQ/delay patterns и командной обработки.
Выбор должен идти от семантики: событие-история или задача-команда, нужен ли replay, порядок, routing, TTL и delay.
Как отвечать на собеседовании
Подчеркните ключевое отличие от Kafka: продюсер пишет в EXCHANGE (типы direct/topic/fanout/headers), а тот по bindings маршрутизирует в очереди — продюсер не знает про очереди. Объясните prefetch (число неподтверждённых сообщений у consumer — регулятор fairness и памяти), manual ack/nack и опасность бесконечного requeue poison-сообщения → ограниченные ретраи + DLQ через Dead Letter Exchange. Для надёжной отправки назовите publisher confirms. Завершите выбором Kafka (event log/replay/порядок в партиции) vs RabbitMQ (work queue/routing/DLQ/TTL/delay).