Профессиональная верстка на React, Next.js и Astro.build по всего 750 рублей в час! Гарантирую качество и соблюдение договорных обязательств.

Pub/Sub в Redis - как использовать паттерн обмена сообщениями Publish/Subscribe

Pub/Sub в Redis - как использовать паттерн обмена сообщениями Publish/Subscribe

Когда вы работаете над приложением, которое должно быть легко обслуживаемым, масштабируемым и производительным, шаблон обмена сообщениями Publish/Subscribe является отличным выбором.

Идея, лежащая в его основе, проста, но мощна. У нас есть отправители, называемые издателями. Их единственная задача — отправлять или публиковать сообщения. Их не волнует, кто их получит и получит ли вообще. Они просто отправляют сообщения и забывают о них. И делают они это с помощью каналов.

Представьте их себе, как, например, телевизионные каналы. У нас есть спортивные каналы, каналы прогноза погоды, кулинарные каналы и так далее. Каждый издатель посылает свои сообщения на определенный канал, и тот, кто подписан на этот канал, сможет получать эти сообщения.

Вот тут-то и вступают в игру подписчики. Они могут подписаться на один или несколько каналов и начать получать транслируемые в них сообщения.

Как мы уже говорили, сообщения должны быть отправлены и забыты. Это означает, что если подписчик подписывается на определенный канал, то все сообщения, которые были отправлены ранее в этом канале, будут ему недоступны.

В силу особенностей подобной архитектуры мы можем легко добиться низкого уровня сопряжения между различными компонентами и обеспечить надежную основу для создания надежных и простых в обслуживании приложений.

Например, представьте себе ситуацию, когда нам необходимо заменить или улучшить издательскую часть нашей системы — добавить больше издателей, больше каналов и т. д. Поскольку эти две части изолированы друг от друга, то есть издателям нет дела до подписчиков и наоборот, мы можем легко это сделать, не беспокоясь о том, что нарушим какую-то другую часть системы. Мы просто добавляем новых издателей. Затем, когда подписчик приходит к соответствующим каналам, он просто начинает их использовать.

Что такое Redis?

Изначально Redis задумывался как решение для кэширования в памяти, как альтернатива своему предку Memcached.

Но сегодня это решение «много в одном», обеспечивающее хранение структур данных in-memory, базу данных ключевых значений, брокерскую обработку сообщений и т. д. Это делает его идеальным кандидатом при создании приложения, которому требуется действительно быстрое кэширование, а также некоторые другие возможности, о которых говорилось выше. Особенно если производительность приложения является критически важной для его регулярного использования.

Сравнение производительности Redis (источник: google)Сравнение производительности Redis (источник: google)

Одним из самых больших преимуществ использования Redis является наличие огромного сообщества и технических ресурсов, которые можно найти в Интернете. Многие из этих ресурсов бесплатны, и есть онлайн-платформы, предлагающие бесплатный уровень.

В арсенале Redis есть и облачное решение. Если вы хотите попробовать его самостоятельно, вы можете перейти сюда и зарегистрировать бесплатную запись или воспользоваться их первоначальным купонным предложением.

Страница регистрации/входа в систему Redis Enterprise Cloud
Страница регистрации/входа в систему Redis Enterprise Cloud

Pub/Sub в Redis

Что такое pub/sub?

Каналы Publish/Subscribe в Redis — это одна из тех возможностей, о которых я не упомянул выше, но она появилась в последних версиях Redis. Это реализация шаблона обмена сообщениями pub/sub, в котором есть издатели и подписчики, обменивающиеся сообщениями по каналам.

Ниже мы вкратце рассмотрим этот паттерн, а затем увидим его на практике в небольшом демонстрационном приложении, которое я подготовил для вас.

Как работает Redis pub/sub?

У нас есть издатели (производители сообщений), каналы (по которым проходят сообщения) и подписчики (получатели сообщений). Кто что получает, зависит только от того, кто на какой канал подписан.

Давайте посмотрим, как это работает на примере:

Если мы создали три издателя, которые будут публиковать сообщения в три разных канала. Назовем их каналами 1, 2 и 3. У нас также есть три подписчика, назовем их подписчиками A, B и C.

Теперь представим, что абонент A прослушивает сообщения на всех трех каналах, т. е. он на них подписан. А абоненты B и C подписаны на каналы 2 и 3. Это означает, что когда любой из трех издателей пошлет сообщение, абонент A его получит. А подписчики B и C будут получать сообщения, отправленные только издателями 2 и 3, поскольку они прослушивают только сообщения по этим каналам (2 и 3).

Обратите внимание, что у нас есть две сущности, использующие канал — одна отправляет, другая получает, — но они абсолютно независимы. Причем отправляемые сообщения не сохраняются. После отправки издателем они забываются. Их получат только те сущности, которые подписаны на них в момент отправки.

Как использовать pub/sub в Redis

Существует огромное количество клиентских библиотек, которые можно использовать с Redis. Существует специальная страница, на которой каждый может выбрать одну из них, в зависимости от потребностей конкретного проекта или просто от предпочитаемого языка программирования.

Люди из Redis также пометили некоторые из этих репозиториев как рекомендуемые, что облегчает выбор, если вы новичок во всем этом.

Для нашего демонстрационного примера я использовал ioredis, полнофункциональный клиент Redis для Node.js. Я выбрал его потому, что пользовательский интерфейс демонстрационного приложения построен на React и Node.js, и мой серверный код довольно хорошо сочетается с ним.

Демонстрация Redis Pub/Sub

Приложение Redis Pub/Sub Visualizer

Время показа!

Идея демонстрационного приложения заключается в том, чтобы наглядно показать, как работает шаблон.

Открыв его в первый раз, вы увидите три кнопки для публикации простых сообщений (новостей) на трех воображаемых телеканалах: Погода, Спорт и Музыка.

Карточки под кнопками публикации — это подписчики. При наведении курсора мыши на любую из них она перевернется на обратную сторону, и вы увидите три кнопки. С помощью каждой из этих кнопок можно подписаться на соответствующий канал.

После того как подписчик будет подписан на канал и вы щелкнете на пиктограмме или кнопке публикации этого канала, на лицевой стороне карточки появится образец новости.

Поиграйте с различными комбинациями издателей/подписчиков и посмотрите на результат.

Надеюсь, это поможет вам лучше понять то, что я объяснил в приведенном примере.

Как запустить демонстрационное приложение локально

Чтобы установить и запустить демонстрационное приложение локально, выполните следующие действия (все команды считаются запущенными из корневого каталога проекта):

Запустите фронтенд:

cd client yarn && yarn dev

Запустить backend:

cd server && yarn yarn start

И, наконец, используйте вашу локальную установку Docker (если у вас ее нет, вы можете получить ее отсюда) для запуска этого проекта:

docker run -p 6379:6379 redislabs/redismod:preview

Это, пожалуй, самый простой способ получить работающую копию Redis локально. Другой вариант — использовать Redis Cloud напрямую и развернуть приложение в Интернете. Этот вариант я пока изучаю, и если мне удастся это сделать, я разверну все приложение и сообщу вам.

В заключение

Эта статья познакомила вас с темой шаблона обмена сообщениями pub/sub. Важно помнить, что всякий раз, когда мы хотим построить высокопроизводительное приложение с низкосвязанной архитектурой и функциями обмена сообщениями в реальном времени, следует использовать паттерн Publish/Subscribe и, в частности, Redis.

На самом деле многие реальные приложения, использующие Redis, основаны на приборных панелях. Это означает, что обычно имеется красивый экран приборной панели, на котором отображаются различные данные, часто обновляемые в реальном времени.

Представьте себе, например, систему, показывающую движение транспорта в определенном районе. Такое программное обеспечение — идеальный кандидат для использования преимуществ pub/sub. И во многих случаях это достигается за счет использования Redis.

В любом случае, как разработчики и инженеры, мы всегда должны ориентироваться на конкретные потребности проекта, над которым работаем. Всякий раз, когда мы принимаем решение о внедрении нового паттерна или технологии, мы должны делать это осторожно и подкреплять серьезными исследованиями.