Что такое fanout в контексте сетевых взаимодействий?

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

Ответ

Fanout ("веерная рассылка") — это архитектурный паттерн в системах обмена сообщениями, при котором одно входящее сообщение или событие доставляется множеству получателей (потребителей) одновременно. Это основа модели Publish/Subscribe (Pub/Sub).

Как это работает:

  1. Издатель (Publisher) отправляет сообщение не напрямую в очередь, а в exchange (топик).
  2. Exchange типа fanout игнорирует ключи маршрутизации и просто копирует сообщение во все очереди, которые с ним связаны.
  3. Каждый Подписчик (Subscriber/Consumer), слушающий свою очередь, получает копию этого сообщения.

Типичный Use Case в PHP-приложениях: Рассылка уведомлений о системном событии (например, UserRegistered) разным независимым сервисам.

// Publisher (используя библиотеку php-amqplib)
$connection = new AMQPStreamConnection('rabbitmq', 5672, 'guest', 'guest');
$channel = $connection->channel();

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

$eventData = json_encode(['user_id' => 123, 'email' => 'user@example.com']);
$msg = new AMQPMessage($eventData);

// Публикуем сообщение в exchange. Ключ маршрутизации (routing_key) не важен для fanout.
$channel->basic_publish($msg, 'user_events');

// Subscriber 1 (Сервис отправки email)
$channel->queue_declare('email_service_queue', false, false, false, false);
$channel->queue_bind('email_service_queue', 'user_events'); // Привязка очереди к exchange
// Subscriber 2 (Сервис аналитики)
$channel->queue_declare('analytics_queue', false, false, false, false);
$channel->queue_bind('analytics_queue', 'user_events');
// Оба сервиса получат одинаковое сообщение.

Преимущества fanout:

  • Слабая связанность: Издатель не знает о существовании или количестве получателей.
  • Масштабируемость: Новые подписчики добавляются без изменений кода издателя.
  • Параллельная обработка: Разные сервисы обрабатывают одно событие независимо и параллельно.

Где используется: Уведомления, логирование в несколько мест, обновления кэша, event-driven архитектура.