EMZETT.
Войти

Паттерн публикации/подписки (publish/subscribe): сообщения многим получателям

Коротко: Отправитель публикует сообщения в теме, не зная получателей; все, кто подписался на тему, их получают.

Подробнее: В publish/subscribe (pub/sub) отправитель (publisher) и получатель (subscriber) разделены. Между ними находится посредник — брокер. Издатель не знает, кто слушает, подписчики не знают, кто отправляет. Это упрощает расширение систем: новый получатель просто подписывается на существующую тему.

Подробности

Строительные блоки

  • Тема (topic) (предмет, канал): имя, под которым публикуются сообщения, например order.new.
  • Издатель (publisher): отправляет сообщения в тему.
  • Подписчик (subscriber): подписывается на темы и обрабатывает входящие сообщения.
  • Брокер: принимает сообщения, распределяет их и может буферизовать. Примеры: брокеры MQTT, Redis pub/sub, Google Pub/Sub, Apache Kafka.

Отличие от очереди

В классической очереди каждое сообщение достаётся ровно одному из нескольких конкурирующих потребителей. В pub/sub каждый подписчик получает копию. Многие системы сочетают оба подхода: несколько сервисов подписываются на тему, а внутри одного сервиса несколько экземпляров делят работу (группы потребителей).

Пример на JavaScript с Redis

// получатель
subscriber.subscribe('order.new', (msg) => console.log('Новый:', msg));
// отправитель
publisher.publish('order.new', JSON.stringify({ id: 42 }));

Сервис выставления счетов и сервис доставки могут подписаться на одну и ту же тему и реагировать независимо друг от друга.

На что обратить внимание

Простой Redis pub/sub ничего не хранит: кто в данный момент не подключён, пропускает сообщение. Для надёжной доставки нужны брокеры с хранилищем и подтверждениями. Поскольку одно и то же сообщение может прийти более одного раза, получатели должны работать идемпотентно. В зависимости от системы порядок гарантируется только в пределах раздела (partition) или вообще не гарантируется.

См. также: Очередь сообщений, Apache Kafka, Паттерн «Наблюдатель», Вебхуки