Redis
Теория: Реалтайм чат с Redis PubSub
Многие современные веб-сайты имеют события, которые отображаются у пользователя в режиме реального времени без перезагрузки страницы. Например, в любой социальной сети нет необходимости перезагружать страницу, чтобы получить новое сообщение от другого пользователя. Как технически устроены такие системы?
Современная архитектура выглядит следующим образом:
- веб-браузер подключается к серверу по веб-сокету (особый тип соединения, который один раз устанавливается и держится. В рамках этого соединения клиент с сервером общаются независимо)
- когда происходит событие, back-end отправляет данные браузеру по веб-сокету
- браузер получает данные и отображает событие в режиме реального времени
Нас интересует back-end часть данной архитектуры. Обычно веб-сокет соединения обслуживаются отдельным микросервисом. Когда со стороны веб-сервера происходит событие, сервер отправляет данные в веб-сокет микросервиса, чтобы передать веб-браузеру.
Как передавать данные от веб-сервера в веб-сокет микросервис? Самое тривиальное решение: делать HTTP запрос. Для небольших приложений с редкими событиями этого будет достаточно. Однако для большинства проектов такое решение не подойдет, потому что HTTP устанавливает TCP соединение на каждом запросе и отправляет много лишней информации в виде заголовков. Например, в мессенджерах, где новые сообщения приходят миллионами, с HTTP все будет работать недопустимо медленно.
В данном случае хорошим решением будет использование брокера сообщений. Он может быть настроен под разные модели доставки сообщений. В примере с мессенджерами идеально подходит модель Pub/Sub (издатель-подписчик). Веб-сокет микросервис подписывается на канал личных сообщений пользователя. В какой-то момент веб-сервер публикует сообщение в канал, и веб-сокет микросервиса отправляет его в браузер. Преимущества этого решения:
- подписчик держит постоянное соединение с брокером сообщений
- издатель отправляет только полезную информацию без лишних заголовков
- пропускная способность такого взаимодействия подходит для высоконагруженных проектов
Redis Pub/Sub
Разберем как Redis реализует модель Pub/Sub на примере личных сообщений в мессенджере.
Веб-сокет микросервис подписывается на события с помощью команды subscribe channel [channel ...]:
После выполнения команды возвращается 1 в случае успешной подписки на канал, и соединение блокируется в ожидании сообщений.
При отправке нового сообщения веб-сервер публикует событие в Redis командой publish channel message:
В ответе на команду publish возвращается количество клиентов, получивших опубликованное сообщение.
Со стороны веб-сокет микросервиса моментально приходит сообщение:
1 означает действие; 2 — канал, из которого получено сообщение; 3 тело сообщения.
Когда использовать Pub/Sub
Стоит отметить, что Redis Pub/Sub используется в тех случаях, когда события могут быть потеряны. Если в момент публикации не будет ни одного подписчика или у пользователя не будет открытого веб-сокет соединения, событие уйдет в никуда. Например, это подходит для нотификаций пользователя о новых сообщениях в мессенджере, потому что при перезагрузке страницы данные будут получены с сервера по API. Однако данная архитектура явно не подходит для отправки уведомлений на электронную почту или SMS.
Резюме
- модель Pub/Sub используется в реалтайм приложениях
- Redis эффективно реализует модель Pub/Sub, позволяя иметь пропускную способность в 1 млн. сообщений в секунду
- подписчик подписывается на события командой
subscribe - издатель публикует события командой
publish





