Какие недостатки у асинхронного взаимодействия через шину сообщений (message bus)?

«Какие недостатки у асинхронного взаимодействия через шину сообщений (message bus)?» — вопрос из категории Архитектура, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Асинхронная коммуникация через шины (RabbitMQ, Kafka, AWS SQS) решает многие задачи масштабирования, но имеет ряд существенных недостатков:

  1. Сложность отладки и мониторинга. Трудно отследить полный путь сообщения (distributed tracing). Нет синхронного ответа об ошибке, проблемы могут проявиться с задержкой в другом сервисе.
  2. Нарушение порядка сообщений. В системах с несколькими консьюмерами или партициями (Kafka) нет гарантии, что сообщения Событие A → Событие B будут обработаны в том же порядке. Это требует идемпотентности или специальной логики.
  3. Потенциальное дублирование обработки. Из-за retry-механизмов, таймаутов или сбоев консьюмера одно и то же сообщение может быть обработано несколько раз.
  4. Задержки (latency). Не подходит для сценариев, требующих немедленного ответа пользователю (синхронный HTTP-запрос).
  5. Усложнение архитектуры и кода. Появляются новые сущности: очереди, обменники, dead-letter queues. Код должен обрабатывать повторные попытки, идемпотентность, компенсирующие транзакции (Saga pattern).

Пример проблемы с порядком:

// Сервис заказов публикует события
$messageBus->dispatch(new OrderCreated($orderId)); // Событие 1
$messageBus->dispatch(new OrderPaid($orderId));    // Событие 2

// Сервис доставки может получить их в порядке: 2, 1
// и попытаться начать доставку несуществующего заказа.

Для борьбы с этим в Kafka можно использовать ключ партиционирования (например, orderId), чтобы события одного заказа попадали в одну партицию и сохраняли порядок.