Ответ
Поведение зависит от флага mandatory, который указывает, что делать с сообщением, если его невозможно доставить в очередь.
1. mandatory: false (значение по умолчанию)
Сообщение будет безвозвратно отброшено брокером. Отправитель не получит никакого уведомления об ошибке. Это поведение называется "fire and forget" и подходит для сценариев, где потеря отдельных сообщений допустима.
2. mandatory: true
Если exchange не существует, брокер вернет сообщение отправителю через механизм Basic.Return. Отправитель должен быть готов обработать это событие.
Практический пример с обработкой возврата:
using RabbitMQ.Client;
using System.Text;
var factory = new ConnectionFactory() { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();
// 1. Подписываемся на событие возврата сообщения
channel.BasicReturn += (sender, args) =>
{
var body = args.Body.ToArray();
var message = Encoding.UTF8.GetString(body);
Console.WriteLine($"[RETURN] Сообщение возвращено!");
Console.WriteLine($" Причина: {args.ReplyText}");
Console.WriteLine($" Exchange: {args.Exchange}");
Console.WriteLine($" Routing Key: {args.RoutingKey}");
Console.WriteLine($" Тело: {message}");
};
// 2. Публикуем сообщение в несуществующий exchange с mandatory=true
var body = Encoding.UTF8.GetBytes("Test Message");
var properties = channel.CreateBasicProperties();
properties.Persistent = true; // Делаем сообщение устойчивым
channel.BasicPublish(
exchange: "non_existent_exchange", // Несуществующий exchange
routingKey: "some.routing.key",
mandatory: true, // Ключевой параметр
basicProperties: properties,
body: body);
Console.WriteLine("Сообщение опубликовано. Ожидайте Basic.Return...");
Вывод в консоли будет примерно таким:
Сообщение опубликовано. Ожидайте Basic.Return...
[RETURN] Сообщение возвращено!
Причина: NO_ROUTE
Exchange: non_existent_exchange
Routing Key: some.routing.key
Тело: Test Message
Рекомендации:
- Всегда используйте
mandatory: trueв системах, где критична гарантированная доставка или необходима мгновенная реакция на ошибки маршрутизации. - Для повышения надежности комбинируйте это с подтверждениями публикации (Publisher Confirms) и устойчивыми сообщениями (
Persistent = true). - В продакшене обязательно реализуйте логику повторной отправки или перемещения "отравленных" сообщений в Dead Letter Exchange (DLX).