Паттерн публикации/подписки (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, Паттерн «Наблюдатель», Вебхуки