Для чего нужен модуль Exchange в RabbitMQ?

«Для чего нужен модуль Exchange в RabbitMQ?» — вопрос из категории Архитектура, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Exchange (обменник) — это сущность внутри брокера RabbitMQ, которая получает сообщения от продюсеров и решает, в какие очереди их направить. Без Exchange продюсер мог бы отправлять сообщения только напрямую в конкретную очередь, что сильно ограничивает гибкость маршрутизации.

Типы Exchange и их практическое применение:

  1. Direct Exchange: Использую для точечной маршрутизации, например, для обработки задач определенного типа. Сообщение с routing_key='image.resize' попадет только в очередь, привязанную с таким же ключом.
  2. Fanout Exchange: Идеален для широковещательных событий. Например, при регистрации пользователя нужно отправить событие в сервис email, сервис аналитики и сервис рекомендаций. Fanout отправит копию сообщения во все привязанные очереди.
  3. Topic Exchange: Мощный инструмент для сложных сценариев. Использую для системы логов, где routing_key='app.backend.error' попадет в очередь для всех ошибок бэкенда (app.backend.*), а routing_key='app.frontend.critical' — в очередь для критических ошибок фронтенда (app.*.critical).
  4. Headers Exchange: Применяю реже, когда логика маршрутизации основана на атрибутах сообщения (заголовках), а не на ключе. Полезно для сложной фильтрации.

Пример объявления Topic Exchange и отправки сообщения (на PHP с библиотекой php-amqplib):

// Объявление exchange типа 'topic' с именем 'application_logs'
$channel->exchange_declare('application_logs', 'topic', false, true, false);

// Привязка очереди 'critical_errors' к exchange с ключом '*.critical'
$channel->queue_bind('critical_errors', 'application_logs', '*.critical');

// Создание и публикация сообщения о критической ошибке в платежном модуле
$messageBody = json_encode(['error' => 'Payment gateway timeout']);
$msg = new AMQPMessage($messageBody, ['delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT]);

// Ключ маршрутизации: 'payments.critical'
$channel->basic_publish($msg, 'application_logs', 'payments.critical');
// Это сообщение будет доставлено в очередь 'critical_errors', так как ключ соответствует шаблону '*.critical'

Таким образом, Exchange — это сердце системы маршрутизации в RabbitMQ, позволяющее реализовать сложные паттерны, такие как Pub/Sub или маршрутизация по событиям, вместо простой "очереди задач".