Какие типы распределения сообщений можно использовать в RabbitMQ
Что проверяют
Понимаете ли вы модель AMQP: продюсер пишет не в очередь, а в exchange, а тот по правилам привязок раскладывает сообщения по очередям. Следом обычно спрашивают, как распределяются сообщения между несколькими воркерами одной очереди и как не потерять сообщение при падении воркера.
Как отвечать
Маршрутизацию определяет тип обменника:
- direct: сообщение уходит в очереди, чей binding key точно совпадает с routing key. Пример: задачи по типу
resize,email; - fanout: копия в каждую привязанную очередь, ключ игнорируется. Широковещательные события, сброс кэшей;
- topic: ключ из слов через точку и шаблоны, где
*заменяет ровно одно слово, а#ноль или больше.order.*.createdпоймаетorder.eu.created, аorder.#любые события заказов; - headers: маршрут по заголовкам сообщения,
x-matchзадаёт, должны совпасть все (all) или любой (any); - default exchange: безымянный direct, к которому каждая очередь привязана по своему имени. Он работает, когда в
pikaпубликуют сexchange=''иrouting_key='tasks'.
Второй уровень это распределение между потребителями. Несколько воркеров на одной очереди конкурируют, брокер раздаёт сообщения по кругу. Чтобы медленный воркер не копил задачи, ставят channel.basic_qos(prefetch_count=1) и подтверждают вручную через basic_ack после обработки, с auto_ack=False. Неподтверждённое сообщение при обрыве соединения вернётся в очередь.
Из Python это pika для синхронного кода, aio-pika для asyncio, а Celery ходит в RabbitMQ через kombu. Для надёжности добавьте dead letter exchange для сообщений, которые не удалось обработать, и quorum-очереди вместо классических.
Где спотыкаются
Думают, что fanout раздаёт копию каждому потребителю. Копию получает каждая очередь, а воркеры одной очереди делят сообщения между собой.
Включают auto_ack=True. Сообщение считается обработанным в момент отправки воркеру, и его падение посреди работы теряет задачу.
Не знают, что сообщение без подходящей привязки молча отбрасывается. Поймать его помогает флаг mandatory при публикации или alternate exchange.