Как использовать Redis Pub/Sub в мессенджерах
12 апреля 2022 г.В настоящее время на большинстве веб-страниц происходит множество событий в реальном времени. Например, социальной сети нужно мгновенно показать новое сообщение от другого пользователя без перезагрузки страницы. Как технически устроены такие системы?
Наиболее распространенная архитектура:
- веб-браузер подключается к серверу через WebSocket (особый тип соединения, которое устанавливается один раз и поддерживается после этого. В рамках этого соединения клиент взаимодействует с сервером самостоятельно)
- при возникновении события сервер отправляет данные в браузер через WebSocket
- браузер получает данные и отображает событие в режиме реального времени
Самая интересная часть этой архитектуры — серверная. Обычно некоторые микросервисы обрабатывают соединения WebSocket. Когда событие происходит на стороне сервера, сервер отправляет его в микрослужбу WebSocket для передачи в веб-браузер.
Как отправить данные с сервера в микросервис WebSocket? Самое простое решение — сделать HTTP-запрос. Этого будет достаточно для небольших приложений с плохим подсчетом событий. Однако это решение не будет работать для большинства проектов, поскольку HTTP устанавливает TCP-соединение при каждом запросе и отправляет ненужную информацию в заголовках. Например, при использовании HTTP все будет работать недопустимо медленно в мессенджерах, где в минуту обрабатываются миллионы сообщений.
В этом случае хорошим решением будет использование брокера сообщений. Его можно настроить для разных моделей доставки сообщений. Модель Pub/Sub (издатель-подписчик) предпочтительнее в примере с мессенджером. Микросервис WebSocket подписывается на личный канал обмена сообщениями пользователя. В какой-то момент веб-сервер публикует сообщение в канале, а микросервис WebSocket отправляет его в браузер.
Плюсы подхода:
- подписчик поддерживает постоянную связь с брокером сообщений
- издатель отправляет только полезную информацию без лишних заголовков
- пропускная способность взаимодействия подходит для высоконагруженных проектов
Redis Pub/Sub
Давайте посмотрим, как Redis реализует модель Pub/Sub на примере личных сообщений в мессенджере.
Микросервис websocket подписывается на события мессенджера с помощью команды subscribe channel [channel ...]
:
``` ударить
127.0.0.1:6379> подписка на сообщения
Чтение сообщений... (нажмите Ctrl-C, чтобы выйти)
1) подписаться
2) "сообщения"
3) (целое) 1
Выполнение команды возвращает 1, если подписка на канал прошла успешно и соединение заблокировано в ожидании сообщений.
При отправке нового сообщения веб-сервер публикует событие в Redis с помощью команды «publish channel message»:
``` ударить
127.0.0.1:6379> публиковать сообщения '{"user_id":123456,"message_id":"f112aa8a-3966-4070-a990-cf7afcdf0eea","message_text":"О, привет Марк!","sent_at":1649294564} '
(целое) 1
Команда publish
возвращает количество клиентов, получивших широковещательное сообщение.
Мгновенно приходит сообщение со стороны микросервиса WebSocket:
``` ударить
1) «сообщение»
2) "сообщения"
3) "{\"user_id\":123456,\"message_id\":\"f112aa8a-3966-4070-a990-cf7afcdf0eea\",\"message_text\":\"О, привет Марк!\",\" send_at\":1649294564}"
1 означает действие; 2 — канал, откуда пришло сообщение; 3 тело сообщения.
Когда использовать Pub/Sub
:::предупреждение
Важное примечание: используйте Redis Pub/Sub только в тех случаях, когда ваш сервер может терять события
Если на момент публикации нет подписчиков или если у пользователя нет открытого соединения WebSocket, событие исчезнет. Например, используйте Pub/Sub для уведомлений о новых сообщениях в мессенджере. Если пользователь онлайн, он увидит любые изменения в режиме реального времени. Но когда пользователь перезагрузит страницу, он получит все данные с сервера по API.
Однако эту архитектуру явно нельзя использовать для отправки электронных писем или SMS-уведомлений.
Вывод
- Модель Pub/Sub используется в приложениях реального времени.
- Redis эффективно реализует модель Pub/Sub, обеспечивая пропускную способность до 1 миллиона сообщений в секунду.
- подписчик подписывается на события с помощью команды
subscribe
- издатель публикует события с помощью команды
publish
Оригинал