Что такое exchange в RabbitMQ
Что проверяют
Понимаете ли вы, что в RabbitMQ публикуют не в очередь, а в exchange, и умеете ли выбрать тип маршрутизации под задачу. В Go к этому добавляется практика: топологию здесь обычно объявляют кодом через клиент, а не готовой конфигурацией.
Как отвечать
Exchange это точка приёма сообщений от издателя и правило их раскладки по очередям. Издатель не пишет в очередь напрямую: он публикует в exchange с ключом маршрутизации, а связи между exchange и очередями решают, кому достанется копия.
Типы:
direct: копия уходит в очереди, чей ключ связывания точно совпал с ключом сообщения;fanout: копия уходит во все связанные очереди, ключ игнорируется;topic: ключ видаorder.created.euсопоставляется с шаблоном связывания, где*заменяет одно слово, а#любое их количество;headers: маршрут выбирается по заголовкам, режим совпадения задаёт аргументx-match.
Отдельно назовите exchange по умолчанию: это безымянный direct, к которому каждая очередь привязана собственным именем. Именно поэтому публикация с пустым именем exchange и ключом, равным имени очереди, работает без всякой настройки, и в примерах на Go встречается чаще всего.
err := ch.PublishWithContext(ctx, "orders", "order.created.eu", false, false, msg)Стоит добавить: сообщение, не подошедшее ни под одну связь, молча пропадает, если не включён флаг mandatory с обработкой возвратов или не назначен альтернативный exchange.
Где спотыкаются
Путают, где живёт шаблон. Звёздочка и решётка допустимы в ключе связывания, а ключ самого сообщения всегда конкретная строка, иначе маршрутизация по теме превращается в лотерею.
Считают, что fanout нужен для распределения нагрузки. Он рассылает копию в каждую очередь, а несколько потребителей на одной очереди делят сообщения между собой, и это ровно противоположные схемы.
Объявляют топологию по-разному в издателе и потребителе. Повторное объявление того же exchange с другим типом или другой долговечностью роняет канал, и в Go это выглядит как внезапно закрытый канал без внятной причины.