Что такое Topic Exchange в RabbitMQ?

«Что такое Topic Exchange в RabbitMQ?» — вопрос из категории Брокеры сообщений, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Topic Exchange — это тип точки обмена (exchange) в RabbitMQ, который маршрутизирует сообщения в очереди на основе совпадения шаблона (pattern matching) ключа маршрутизации (routing key) сообщения и шаблона привязки (binding key) очереди.

Ключевые особенности:

  • Гибкая маршрутизация: Позволяет реализовать сложные сценарии, такие как подписка на категории событий (например, логи определённого уровня и источника).
  • Специальные символы в binding key:
    • * (звездочка) — заменяет ровно одно слово в ключе.
    • # (решетка) — заменяет ноль или более слов.

Пример использования (C# с библиотекой RabbitMQ.Client):

// 1. Объявление exchange типа 'topic'
channel.ExchangeDeclare(exchange: "logs_topic", type: ExchangeType.Topic);

// 2. Привязка очередей с разными шаблонами
// Эта очередь получит все ошибки любого приложения
channel.QueueBind(queue: "all_errors",
                  exchange: "logs_topic",
                  routingKey: "*.error");

// Эта очередь получит все логи от приложения 'app1'
channel.QueueBind(queue: "app1_logs",
                  exchange: "logs_topic",
                  routingKey: "app1.*");

// Эта очередь получит всё, что связано с платежами и ошибками
channel.QueueBind(queue: "critical_payment_errors",
                  exchange: "logs_topic",
                  routingKey: "payment.#.error");

// 3. Публикация сообщений с разными routing keys
// Попадёт в очереди: 'all_errors' и 'app1_logs'
var body1 = Encoding.UTF8.GetBytes("App1 error log");
channel.BasicPublish(exchange: "logs_topic",
                     routingKey: "app1.error",
                     basicProperties: null,
                     body: body1);

// Попадёт ТОЛЬКО в очередь: 'app1_logs'
var body2 = Encoding.UTF8.GetBytes("App1 info log");
channel.BasicPublish(exchange: "logs_topic",
                     routingKey: "app1.info",
                     basicProperties: null,
                     body: body2);

Практическое применение: Создание гибких систем событий (event-driven architecture), где потребители могут динамически подписываться на интересующие их категории сообщений, например, для распределённого логирования, нотификаций или обновления кэша.