← Назад к вопросам

Какие знаешь типы exchange в RabbitMQ?

2.3 Middle🔥 81 комментариев
#Очереди и брокеры сообщений

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Типы Exchange в RabbitMQ

В RabbitMQ Exchange — это сущность, которая получает сообщения от продюсеров и направляет их в очереди по определённым правилам, называемым типами exchange. Тип exchange определяет логику маршрутизации сообщений. Всего существует четыре основных типа, каждый из которых решает конкретные задачи в распределённых системах.

1. Direct Exchange (Прямой обменник)

Это наиболее простой и часто используемый тип. Он маршрутизирует сообщения в очереди на основе точного совпадения ключа маршрутизации (routing key). Продюсер указывает ключ, а потребитель привязывает свою очередь к exchange с этим ключом.

  • Как работает: Сообщение направляется в очереди, чей routing key полностью совпадает с ключом сообщения.
  • Пример использования: Точечная отправка сообщений определённым получателям, например, уведомления для конкретного пользователя.
  • Пример настройки в коде:
<?php
// Создание direct exchange
$channel->exchange_declare('direct_logs', 'direct', false, false, false);

// Отправка сообщения с ключом 'error'
$channel->basic_publish(
    new AMQPMessage('Сообщение об ошибке'),
    'direct_logs',
    'error' // routing key
);
// Очередь должна быть привязана с ключом 'error', чтобы получить это сообщение
?>

2. Fanout Exchange (Трансляционный обменник)

Этот тип игнорирует ключи маршрутизации и рассылает сообщения во все привязанные очереди. Он идеален для широковещательных сценариев.

  • Как работает: Каждое сообщение копируется во все очереди, привязанные к exchange, независимо от routing key.
  • Пример использования: Рассылка обновлений состояния системы всем подписчикам или реализация pub/sub.
  • Пример настройки:
<?php
// Создание fanout exchange
$channel->exchange_declare('notifications', 'fanout', false, false, false);

// Привязка нескольких очередей без указания ключа
$channel->queue_bind('queue1', 'notifications');
$channel->queue_bind('queue2', 'notifications');

// Отправка сообщения — оно попадёт в обе очереди
$channel->basic_publish(
    new AMQPMessage('Новое уведомление для всех'),
    'notifications',
    '' // ключ игнорируется
);
?>

3. Topic Exchange (Тематический обменник)

Позволяет выполнять гибкую маршрутизацию на основе шаблонов ключей. Ключи маршрутизации представляют собой строки, разделённые точками, а в привязках очередей используются wildcards:

  • * (звёздочка) — заменяет ровно одно слово.

  • # (решётка) — заменяет ноль или более слов.

  • Как работает: Сообщение направляется в очереди, чей шаблон ключа совпадает с routing key сообщения.

  • Пример использования: Сложные системы маршрутизации, например, фильтрация логов по уровню (app.error) или категориям.

  • Пример настройки:

<?php
// Создание topic exchange
$channel->exchange_declare('topic_logs', 'topic', false, false, false);

// Привязка очереди с шаблоном 'app.*.error'
$channel->queue_bind('queue_errors', 'topic_logs', 'app.*.error');

// Сообщение с ключом 'app.auth.error' попадёт в очередь
$channel->basic_publish(
    new AMQPMessage('Ошибка аутентификации'),
    'topic_logs',
    'app.auth.error'
);
?>

4. Headers Exchange (Заголовочный обменник)

Использует для маршрутизации не ключи, а заголовки сообщений (пары ключ-значение). Привязка очередей задаётся с набором условий на заголовки.

  • Как работает: Сообщение направляется в очереди, чьи условия в заголовках совпадают с заголовками сообщения. Есть два режима сопоставления:
    - `x-match: all` — должны совпасть все заголовки (логическое И).
    - `x-match: any` — достаточно совпадения хотя бы одного заголовка (логическое ИЛИ).
  • Пример использования: Сложная фильтрация на основе метаданных, например, маршрутизация по типу устройства или региону.
  • Пример настройки:
<?php
// Создание headers exchange
$channel->exchange_declare('headers_exchange', 'headers', false, false, false);

// Привязка очереди с условием (x-match: all)
$channel->queue_bind('queue_mobile', 'headers_exchange', '', false, [
    'device' => 'mobile',
    'os' => 'android',
    'x-match' => 'all'
]);

// Отправка сообщения с заголовками
$headers = ['device' => 'mobile', 'os' => 'android'];
$message = new AMQPMessage('Сообщение для Android', ['headers' => $headers]);
$channel->basic_publish($message, 'headers_exchange', ''); // routing key не используется
?>

Ключевые различия и выбор типа

  • Direct — для точной маршрутизации, когда один ключ соответствует одной очереди.
  • Fanout — для широковещания, когда сообщение нужно дублировать всем потребителям.
  • Topic — для гибкой маршрутизации по иерархическим ключам (например, системы логирования или уведомлений).
  • Headers — для маршрутизации на основе метаданных, когда ключи неудобны.

На практике в PHP-приложениях чаще всего используются direct и fanout для простых сценариев, а topic — для сложных систем с множеством подписчиков. Выбор типа зависит от архитектурных требований: например, для микросервисной коммуникации подходит direct, а для событийных систем — fanout или topic. Понимание этих типов позволяет эффективно проектировать асинхронные взаимодействия в backend.