Хранение данных на сервере Webapp: память против базы данных - PullRequest
0 голосов
/ 24 января 2020

Мы создаем веб-приложение в Go с базой данных MySQL. Нашим пользователям разрешено иметь только одного активного клиента одновременно. Как и Spotify, вы можете слушать музыку только на одном устройстве одновременно. Для этого я сделал карту с ключом идентификаторами пользователей и ссылкой на их активное соединение с веб-сокетом в качестве значения. На основе идентификатора websocket, который клиент должен отправить в заголовке запроса, мы можем определить, когда запрос поступает из его активного сеанса.

Мой вопрос заключается в том, рекомендуется ли хранить данные (в данном случае карту с идентификаторами пользователей и веб-сокетами) в глобальном пространстве или лучше хранить их в базе данных.

Мы не ожидаем охватить более 10000 одновременно активных клиентов. Среднее значение, вероятно, будет около 1000.

1 Ответ

2 голосов
/ 24 января 2020

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

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

Также возможно иметь отдельную службу, которая обрабатывает входящий запрос и запрашивает все службы веб-сокетов, имеет ли какая-либо из них соединение, указанное в запросе. Это можно сделать, если добавить очередь pub / sub и каждая служба веб-сокетов подписывается на каналы для всех своих идентификаторов веб-сокетов, а служба, которая получает запрос, затем публикует идентификатор веб-сокета, а затем службы веб-сокетов могут отправлять ответы назад по отдельному каналу. если у них есть эта связь. Вы должны решить, как обрабатывать, если никто не отвечает (ни у одной службы websocket нет идентификатора websocket). Либо канал не существует, либо вы ожидаете ответа в течение указанного c времени. Или вы можете опубликовать sh вопрос по общей теме c и ожидать, что все службы веб-сокетов ответят (да или нет).

А в отношении того, нужно ли вам его масштабировать, я полагаю, что это зависит в основном от базовый сервер, на котором вы запускаете сервис. Если я правильно понимаю, служба websocket в основном не будет делать ничего, кроме как отслеживать свои соединения (вы должны добавить пинг-понг, чтобы узнать, потеряны ли соединения). Тогда ваши ограничения должны в основном заключаться в том, сколько файловых дескрипторов ваша система может обрабатывать одновременно. Если этот предел намного превышает ожидаемое максимальное количество пользователей, то запуск только одного сервера и хранение всего в памяти может быть хорошим решением!

Наконец, если вы собираетесь открыть веб-розетку для всех пользователей, почему бы не сделать все «другое» общение через это соединение веб-сокета, вместо того, чтобы они отправляли HTTP-запросы со своим идентификатором веб-сокета? Возможно, HTTP лучше подходит для вашего случая использования, но вам стоит подумать:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...