Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Реалтайм чат с Redis PubSub Основы Redis

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

Современная архитектура выглядит следующим образом:

  • веб-браузер подключается к серверу по веб-сокету (особый тип соединения, который один раз устанавливается и держится. В рамках этого соединения клиент с сервером общаются независимо)
  • когда происходит событие, back-end отправляет данные браузеру по веб-сокету
  • браузер получает данные и отображает событие в режиме реального времени

backend_websocket

Нас интересует back-end часть данной архитектуры. Обычно веб-сокет соединения обслуживаются отдельным микросервисом. Когда со стороны веб-сервера происходит событие, сервер отправляет данные в веб-сокет микросервиса, чтобы передать веб-браузеру.

websocket_microservice

Как передавать данные от веб-сервера в веб-сокет микросервис? Самое тривиальное решение: делать HTTP запрос. Для небольших приложений с редкими событиями этого будет достаточно. Однако для большинства проектов такое решение не подойдет, потому что HTTP устанавливает TCP соединение на каждом запросе и отправляет много лишней информации в виде заголовков. Например, в мессенджерах, где новые сообщения приходят миллионами, с HTTP все будет работать недопустимо медленно.

В данном случае хорошим решением будет использование брокера сообщений. Он может быть настроен под разные модели доставки сообщений. В примере с мессенджерами идеально подходит модель Pub/Sub (издатель-подписчик). Веб-сокет микросервис подписывается на канал личных сообщений пользователя. В какой-то момент веб-сервер публикует сообщение в канал, и веб-сокет микросервис отправляет его в браузер. Преимущества этого решения:

  • подписчик держит постоянное соединение с брокером сообщений
  • издатель отправляет только полезную информацию без лишних заголовков
  • пропускная способность такого взаимодействия подходит для высоконагруженных проектов

message_broker_web_socket

Redis Pub/Sub

Разберем как Redis реализует модель Pub/Sub на примере личных сообщений в мессенджере.

Веб-сокет микросервис подписывается на события с помощью команды subscribe channel [channel ...]:

127.0.0.1:6379> subscribe messages
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "messages"
3) (integer) 1

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

При отправке нового сообщения веб-сервер публикует событие в Redis командой publish channel message:

127.0.0.1:6379> publish messages '{"user_id":55,"message_id":"d1356e62-f33f-412c-b47c-ff107f3e88b1","message_text":"Oh, hi Mark!","sent_at":1642741377}'
(integer) 1

В ответе на команду publish возвращается количество клиентов, получивших опубликованное сообщение.

Со стороны веб-сокет микросервиса моментально приходит сообщение:

1) "message"
2) "messages"
3) "{\"user_id\":55,\"message_id\":\"d1356e62-f33f-412c-b47c-ff107f3e88b1\",\"message_text\":\"Oh, hi Mark!\",\"sent_at\":1642741377}"

1 означает действие; 2 — канал, из которого получено сообщение; 3 тело сообщения.

Когда использовать Pub/Sub

Стоит отметить, что Redis Pub/Sub используется в тех случаях, когда события могут быть потеряны. Если в момент публикации не будет ни одного подписчика или у пользователя не будет открытого веб-сокет соединения, событие уйдет в никуда. Например, это подходит для нотификаций пользователя о новых сообщениях в мессенджере, потому что при перезагрузке страницы данные будут получены с сервера по API. Однако данная архитектура явно не подходит для отправки уведомлений на электронную почту или SMS.

Резюме

  • модель Pub/Sub используется в реалтайм приложениях
  • Redis эффективно реализует модель Pub/Sub, позволяя иметь пропускную способность в 1 млн. сообщений в секунду
  • подписчик подписывается на события командой subscribe
  • издатель публикует события командой publish

Дополнительные материалы

  1. Redis Pub/Sub
  2. Redis PUBLISH command
  3. Redis SUBSCRIBE command

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
900
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 130 курсов, 2000+ часов теории
  • 900 практических заданий в браузере
  • 360 000 студентов
Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff

Используйте Хекслет по максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»

Изображение Тото

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