Модель издатель-подписчик
Модель издатель-подписчик (также известная как шаблон «издатель-подписчик», от англ. Publish-Subscribe pattern, Pub/Sub) — это архитектурный шаблон обмена сообщениями, при котором отправители (издатели) не отправляют данные напрямую конкретным получателям (подписчикам), а публикуют сообщения в общем канале или через брокер сообщений, не зная, кто и как их будет обрабатывать. Подписчики, в свою очередь, получают только те сообщения, на которые они подписались, и не имеют информации об издателях. Этот шаблон обеспечивает слабую связанность компонентов системы, что является его ключевым преимуществом.
История
Концепция модели «издатель-подписчик» возникла в 1980-х годах в контексте развития распределённых систем и объектно-ориентированного программирования. Одним из ранних примеров её реализации стала система новостей Usenet, где пользователи могли подписываться на тематические группы новостей (newsgroups) и получать сообщения, опубликованные другими участниками. В 1990-х годах шаблон получил широкое распространение в корпоративных информационных системах, особенно в области интеграции приложений (Enterprise Application Integration, EAI). В 2000-х годах, с развитием облачных вычислений и микросервисной архитектуры, Pub/Sub стал одним из основных паттернов для построения масштабируемых и отказоустойчивых систем.
Принцип работы
Основу модели составляют три ключевых компонента:
- Издатель (Publisher): компонент, который создаёт и отправляет сообщения. Издатель не знает, сколько подписчиков получит его сообщение и как они его обработают. Он лишь публикует сообщение в определённый канал или тему.
- Подписчик (Subscriber): компонент, который выражает заинтересованность в получении определённых типов сообщений. Подписчик регистрирует свою подписку на один или несколько каналов (тем) и получает все сообщения, опубликованные в них.
- Брокер сообщений (Message Broker) или Канал (Channel): посредник, который принимает сообщения от издателей и доставляет их всем подписчикам, подписанным на соответствующий канал. Брокер отвечает за маршрутизацию, фильтрацию, а часто и за хранение сообщений (очереди), обеспечивая асинхронность и надёжность доставки.
Процесс обмена сообщениями выглядит следующим образом:
- Подписчик регистрируется на брокере, указывая, какие темы его интересуют.
- Издатель отправляет сообщение брокеру, указывая тему.
- Брокер получает сообщение, определяет всех подписчиков на данную тему и доставляет им копию сообщения.
- Подписчик получает сообщение и обрабатывает его.
Ключевые характеристики
- Слабая связанность (Loose Coupling): издатели и подписчики не зависят друг от друга. Они могут быть созданы, изменены или удалены независимо, пока соблюдают контракт на формат сообщений и названия тем.
- Асинхронность (Asynchrony): издатель не блокируется в ожидании ответа от подписчика. Он отправляет сообщение и продолжает свою работу. Подписчик обрабатывает сообщение, когда у него есть для этого ресурсы.
- Масштабируемость (Scalability): можно легко добавлять новых издателей и подписчиков без изменения существующей инфраструктуры. Брокер может быть кластеризован для обработки большого количества сообщений.
- Фильтрация сообщений (Message Filtering): подписчики получают только те сообщения, которые им нужны, что снижает нагрузку на сеть и упрощает обработку.
Классификация
Модель «издатель-подписчик» реализуется в двух основных вариантах, различающихся способом фильтрации сообщений:
Фильтрация по темам (Topic-based)
Это наиболее распространённый тип. Сообщения публикуются в логические каналы, называемые темами (topics). Подписчик подписывается на одну или несколько тем и получает все сообщения, опубликованные в этих темах. Например, темами могут быть «заказы», «ошибки», «логи». Подписчик, подписавшийся на тему «заказы», будет получать все сообщения, связанные с заказами.
Фильтрация по содержимому (Content-based)
В этом типе подписчик задаёт не тему, а критерии для фильтрации содержимого самого сообщения. Брокер анализирует каждое сообщение и доставляет его только тем подписчикам, чьи критерии совпадают. Например, подписчик может указать: «доставлять все сообщения, где поле "тип" равно "ошибка" и поле "уровень" больше 5». Фильтрация по содержимому более гибкая, но требует от брокера больших вычислительных ресурсов для анализа каждого сообщения.
Применение
Модель «издатель-подписчик» широко используется в различных областях информационных технологий:
- Микросервисная архитектура: для асинхронного обмена событиями между микросервисами. Например, сервис оформления заказа публикует событие «Заказ создан», а сервисы логистики, уведомлений и бухгалтерии подписываются на него и обрабатывают независимо.
- Системы обмена мгновенными сообщениями (чат-боты, мессенджеры): для доставки сообщений от одного отправителя множеству получателей (например, в групповых чатах).
- Интернет вещей (IoT): для сбора данных с множества датчиков (издателей) и их обработки различными аналитическими сервисами (подписчиками).
- Уведомления и оповещения: push-уведомления в мобильных приложениях, email-рассылки, системы мониторинга, где событие (например, превышение порога нагрузки) публикуется, а все заинтересованные системы (администраторы, системы автоматического масштабирования) получают уведомление.
- Потоковая обработка данных (Stream Processing): системы вроде Apache Kafka, Amazon Kinesis или Google Cloud Pub/Sub, которые позволяют обрабатывать непрерывные потоки событий в реальном времени.
- Разработка игр: для синхронизации состояния игры между клиентами и сервером, а также для реализации игровых событий.
Примеры реализации
- Apache Kafka: распределённая платформа для потоковой передачи данных, часто используемая как высокопроизводительный брокер сообщений в модели Pub/Sub. Широко применяется в крупных корпоративных системах, особенно в России (например, в Сбере, Яндексе, Тинькофф).
- RabbitMQ: популярный брокер сообщений, поддерживающий как модель «точка-точка» (очереди), так и модель «издатель-подписчик» (через обменники и привязки).
- Redis Pub/Sub: встроенная функция в Redis, позволяющая реализовать лёгкую и быструю модель Pub/Sub без сохранения сообщений на диске.
- Google Cloud Pub/Sub: облачный сервис от Google, предоставляющий масштабируемую и надёжную инфраструктуру для асинхронного обмена сообщениями.
- MQTT (Message Queuing Telemetry Transport): лёгкий протокол обмена сообщениями, оптимизированный для IoT-устройств с ограниченными ресурсами. Работает по модели «издатель-подписчик» через брокер.
Критика и ограничения
Несмотря на свои преимущества, модель «издатель-подписчик» имеет и ряд недостатков:
- Сложность отладки и тестирования: из-за асинхронности и слабой связанности становится сложнее отследить поток данных и понять, почему определённое сообщение не было обработано или было обработано неверно. Трассировка распределённых транзакций требует специальных инструментов.
- Гарантии доставки: в распределённой системе сложно гарантировать, что сообщение будет доставлено ровно один раз (exactly-once). Чаще всего реализуются гарантии «не более одного раза» (at-most-once) или «как минимум один раз» (at-least-once), что может приводить к дублированию сообщений.
- Зависимость от брокера: брокер сообщений становится единой точкой отказа (single point of failure) и узким местом производительности. Для обеспечения отказоустойчивости требуется его кластеризация и репликация, что усложняет инфраструктуру.
- Управление схемами данных: при изменении формата сообщения (например, добавлении нового поля) необходимо синхронизировать всех издателей и подписчиков, чтобы избежать ошибок десериализации. Для решения этой проблемы используются реестры схем (Schema Registry).
- Проблема «шумных соседей»: один подписчик, обрабатывающий сообщения медленно, может задерживать доставку сообщений другим подписчикам, если брокер не использует отдельные очереди для каждого подписчика.
В России
Модель «издатель-подписчик» активно применяется в российских IT-компаниях и государственных информационных системах. В связи с политикой импортозамещения, наряду с зарубежными решениями (Apache Kafka, RabbitMQ), разрабатываются и используются отечественные аналоги, такие как:
- Arenadata Queue: платформа потоковой обработки данных на базе Apache Kafka, сертифицированная для использования в госорганах.
- Yandex Managed Service for Apache Kafka: облачный сервис от Яндекса, предоставляющий управляемый кластер Kafka.
- HiveMQ: платформа для IoT, поддерживающая MQTT, имеет российские представительства и используется в промышленности.
Источники
- Gamma, E., Helm, R., Johnson, R., Vlissides, J. (1994). Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley. (Глава о паттерне Observer, который является предшественником Pub/Sub).
- Hohpe, G., Woolf, B. (2003). Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions. Addison-Wesley.
- Kleppmann, M. (2017). Designing Data-Intensive Applications: The Big Ideas Behind Reliable, Scalable, and Maintainable Systems. O'Reilly Media. (Глава 11 «Stream Processing»).
- Документация Apache Kafka. Kafka Documentation. The Apache Software Foundation.
- Документация RabbitMQ. RabbitMQ Tutorials. VMware.
- Документация Google Cloud Pub/Sub. Google Cloud Pub/Sub Documentation. Google.
- Документация Arenadata. Arenadata Queue. Arenadata.
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →