0 added
0 removed
Original
2026-01-01
Modified
2026-02-26
1
<p>Многие современные веб-сайты имеют события, которые отображаются у пользователя в режиме реального времени без перезагрузки страницы. Например, в любой социальной сети нет необходимости перезагружать страницу, чтобы получить новое сообщение от другого пользователя. Как технически устроены такие системы?</p>
1
<p>Многие современные веб-сайты имеют события, которые отображаются у пользователя в режиме реального времени без перезагрузки страницы. Например, в любой социальной сети нет необходимости перезагружать страницу, чтобы получить новое сообщение от другого пользователя. Как технически устроены такие системы?</p>
2
<p>Современная архитектура выглядит следующим образом:</p>
2
<p>Современная архитектура выглядит следующим образом:</p>
3
<ul><li>веб-браузер подключается к серверу по веб-сокету (особый тип соединения, который один раз устанавливается и держится. В рамках этого соединения клиент с сервером общаются независимо)</li>
3
<ul><li>веб-браузер подключается к серверу по веб-сокету (особый тип соединения, который один раз устанавливается и держится. В рамках этого соединения клиент с сервером общаются независимо)</li>
4
<li>когда происходит событие, back-end отправляет данные браузеру по веб-сокету</li>
4
<li>когда происходит событие, back-end отправляет данные браузеру по веб-сокету</li>
5
<li>браузер получает данные и отображает событие в режиме реального времени</li>
5
<li>браузер получает данные и отображает событие в режиме реального времени</li>
6
</ul><p>Нас интересует back-end часть данной архитектуры. Обычно веб-сокет соединения обслуживаются отдельным микросервисом. Когда со стороны веб-сервера происходит событие, сервер отправляет данные в веб-сокет микросервиса, чтобы передать веб-браузеру.</p>
6
</ul><p>Нас интересует back-end часть данной архитектуры. Обычно веб-сокет соединения обслуживаются отдельным микросервисом. Когда со стороны веб-сервера происходит событие, сервер отправляет данные в веб-сокет микросервиса, чтобы передать веб-браузеру.</p>
7
<p>Как передавать данные от веб-сервера в веб-сокет микросервис? Самое тривиальное решение: делать HTTP запрос. Для небольших приложений с редкими событиями этого будет достаточно. Однако для большинства проектов такое решение не подойдет, потому что HTTP устанавливает TCP соединение на каждом запросе и отправляет много лишней информации в виде заголовков. Например, в мессенджерах, где новые сообщения приходят миллионами, с HTTP все будет работать недопустимо медленно.</p>
7
<p>Как передавать данные от веб-сервера в веб-сокет микросервис? Самое тривиальное решение: делать HTTP запрос. Для небольших приложений с редкими событиями этого будет достаточно. Однако для большинства проектов такое решение не подойдет, потому что HTTP устанавливает TCP соединение на каждом запросе и отправляет много лишней информации в виде заголовков. Например, в мессенджерах, где новые сообщения приходят миллионами, с HTTP все будет работать недопустимо медленно.</p>
8
<p>В данном случае хорошим решением будет использование брокера сообщений. Он может быть настроен под разные модели доставки сообщений. В примере с мессенджерами идеально подходит модель Pub/Sub (издатель-подписчик). Веб-сокет микросервис подписывается на канал личных сообщений пользователя. В какой-то момент веб-сервер публикует сообщение в канал, и веб-сокет микросервиса отправляет его в браузер. Преимущества этого решения:</p>
8
<p>В данном случае хорошим решением будет использование брокера сообщений. Он может быть настроен под разные модели доставки сообщений. В примере с мессенджерами идеально подходит модель Pub/Sub (издатель-подписчик). Веб-сокет микросервис подписывается на канал личных сообщений пользователя. В какой-то момент веб-сервер публикует сообщение в канал, и веб-сокет микросервиса отправляет его в браузер. Преимущества этого решения:</p>
9
<ul><li>подписчик держит постоянное соединение с брокером сообщений</li>
9
<ul><li>подписчик держит постоянное соединение с брокером сообщений</li>
10
<li>издатель отправляет только полезную информацию без лишних заголовков</li>
10
<li>издатель отправляет только полезную информацию без лишних заголовков</li>
11
<li>пропускная способность такого взаимодействия подходит для высоконагруженных проектов</li>
11
<li>пропускная способность такого взаимодействия подходит для высоконагруженных проектов</li>
12
</ul><h2>Redis Pub/Sub</h2>
12
</ul><h2>Redis Pub/Sub</h2>
13
<p>Разберем как Redis реализует модель Pub/Sub на примере личных сообщений в мессенджере.</p>
13
<p>Разберем как Redis реализует модель Pub/Sub на примере личных сообщений в мессенджере.</p>
14
<p>Веб-сокет микросервис подписывается на события с помощью команды subscribe channel [channel ...]:</p>
14
<p>Веб-сокет микросервис подписывается на события с помощью команды subscribe channel [channel ...]:</p>
15
<p>После выполнения команды возвращается 1 в случае успешной подписки на канал, и соединение блокируется в ожидании сообщений.</p>
15
<p>После выполнения команды возвращается 1 в случае успешной подписки на канал, и соединение блокируется в ожидании сообщений.</p>
16
<p>При отправке нового сообщения веб-сервер публикует событие в Redis командой publish channel message:</p>
16
<p>При отправке нового сообщения веб-сервер публикует событие в Redis командой publish channel message:</p>
17
<p>В ответе на команду publish возвращается количество клиентов, получивших опубликованное сообщение.</p>
17
<p>В ответе на команду publish возвращается количество клиентов, получивших опубликованное сообщение.</p>
18
<p>Со стороны веб-сокет микросервиса моментально приходит сообщение:</p>
18
<p>Со стороны веб-сокет микросервиса моментально приходит сообщение:</p>
19
<p><em>1</em>означает действие;<em>2</em>- канал, из которого получено сообщение;<em>3</em>тело сообщения.</p>
19
<p><em>1</em>означает действие;<em>2</em>- канал, из которого получено сообщение;<em>3</em>тело сообщения.</p>
20
<h3>Когда использовать Pub/Sub</h3>
20
<h3>Когда использовать Pub/Sub</h3>
21
<p>Стоит отметить, что Redis Pub/Sub используется в тех случаях, когда события могут быть потеряны. Если в момент публикации не будет ни одного подписчика или у пользователя не будет открытого веб-сокет соединения, событие уйдет в никуда. Например, это подходит для нотификаций пользователя о новых сообщениях в мессенджере, потому что при перезагрузке страницы данные будут получены с сервера по API. Однако данная архитектура явно не подходит для отправки уведомлений на электронную почту или SMS.</p>
21
<p>Стоит отметить, что Redis Pub/Sub используется в тех случаях, когда события могут быть потеряны. Если в момент публикации не будет ни одного подписчика или у пользователя не будет открытого веб-сокет соединения, событие уйдет в никуда. Например, это подходит для нотификаций пользователя о новых сообщениях в мессенджере, потому что при перезагрузке страницы данные будут получены с сервера по API. Однако данная архитектура явно не подходит для отправки уведомлений на электронную почту или SMS.</p>
22
<h2>Резюме</h2>
22
<h2>Резюме</h2>
23
<ul><li>модель Pub/Sub используется в реалтайм приложениях</li>
23
<ul><li>модель Pub/Sub используется в реалтайм приложениях</li>
24
<li>Redis эффективно реализует модель Pub/Sub, позволяя иметь пропускную способность в 1 млн. сообщений в секунду</li>
24
<li>Redis эффективно реализует модель Pub/Sub, позволяя иметь пропускную способность в 1 млн. сообщений в секунду</li>
25
<li>подписчик подписывается на события командой subscribe</li>
25
<li>подписчик подписывается на события командой subscribe</li>
26
<li>издатель публикует события командой publish</li>
26
<li>издатель публикует события командой publish</li>
27
</ul>
27
</ul>