Ответ
Да, это одна из основных архитектурных возможностей RabbitMQ. Один exchange может рассылать сообщения множеству очередей, к каждой из которых могут быть подключены свои потребители. Механизм рассылки зависит от типа exchange и routing key.
Пример: Fanout Exchange для широковещательной рассылки
using var channel = connection.CreateModel();
// Объявляем fanout exchange (рассылает всем привязанным очередям)
channel.ExchangeDeclare(exchange: "logs", type: ExchangeType.Fanout);
// Объявляем и привязываем две независимые очереди
var queue1 = channel.QueueDeclare(queue: "log_queue_1").QueueName;
channel.QueueBind(queue: queue1, exchange: "logs", routingKey: string.Empty);
var queue2 = channel.QueueDeclare(queue: "log_queue_2").QueueName;
channel.QueueBind(queue: queue2, exchange: "logs", routingKey: string.Empty);
// Создаём и запускаем потребителей для каждой очереди
var consumer1 = new EventingBasicConsumer(channel);
consumer1.Received += (model, ea) => { /* Обработка для сервиса A */ };
channel.BasicConsume(queue: queue1, autoAck: true, consumer: consumer1);
var consumer2 = new EventingBasicConsumer(channel);
consumer2.Received += (model, ea) => { /* Обработка для сервиса B */ };
channel.BasicConsume(queue: queue2, autoAck: true, consumer: consumer2);
Ключевые сценарии и типы exchange:
- Fanout: Сообщение копируется во все привязанные очереди (широковещание).
- Direct/Topic: Сообщение попадает только в очереди, чьи ключи привязки (binding key) совпадают с routing key сообщения (селективная рассылка).
- Балансировка нагрузки: Для параллельной обработки сообщений из одной очереди создайте несколько потребителей на эту очередь. RabbitMQ будет распределять сообщения между ними по алгоритму round-robin (при условии, что не включен режим
prefetchилиack).
Практический вывод: Exchange выступает как маршрутизатор, позволяя реализовать паттерны "публикатор-подписчик" (Pub/Sub), маршрутизацию и балансировку нагрузки между множеством потребителей.