приведет ли параллелизм к сокету.сбой ввода-вывода узлов

#node.js #sockets #concurrency

Вопрос:

Хорошо, я разрабатываю игру, которая потребует реального общения, поэтому я использую сокет.io в этом, поэтому в настоящее время я пытаюсь справиться с отключением игры, меня беспокоит, что одновременно может произойти другое событие, в то время как я справляюсь с отключением, из-за которого игра зависает. Я знаю, что nodejs однопоточен, но что, если я запускаю несколько контейнеров для своего сервера, я знаю, что должен использовать баланс нагрузки, чтобы запросы определенного сокета отправлялись в один и тот же экземпляр, но это может привести к тому, что одновременное событие будет отправлено при отключении пользователя? Так как же это можно было сделать, или я что-то пропустил при масштабировании сокета.ио в моем бэкэнде?

Решение, о котором я подумал, состоит в том, что я мог бы сбалансировать запросы по GameID, чтобы пользователи, участвующие в одной и той же игре, в конечном итоге присоединились к одному и тому же экземпляру моего сервера, но я понятия не имею, применимо ли что-то подобное

Ответ №1:

В этом контексте узел yes является «однопоточным» с точки зрения eventloop, поэтому все ваши запросы будут помещаться в очередь по мере их поступления.

Что это значит, если вы используете сокет.ввод-вывод для вашей «игры», тогда каждый вывод на сервер будет выполняться синхронно один за другим. Теперь, с учетом сказанного, Node здесь очень эффективен, но при большой нагрузке или длительных / блокирующих сценариях может привести сервер к обходу.

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

НО.. это оставляет нас в некотором затруднении, если нам нужно поддерживать состояние, потому что PM2 фактически создает новую версию вашего приложения на каждом «ядре», оно не может общаться между каждым экземпляром, что означает, что сеансы не разделяются между запущенными экземплярами и файлы, хранящиеся на каждой виртуальной машине, доступны между и т. Д..

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

  1. Серверы узлов ( это может быть несколько виртуальных машин с интерфейсом LB или контейнером )
  2. Сервер Redis ( здесь вы будете хранить информацию о сеансах И сокет.данные ввода-вывода )

Теперь есть много способов создать это, но в качестве примера может быть один из способов (предполагая, что вы будете использовать pm2 для кластеризации, которая у вас была бы)

  1. Приложение игрового узла — 2 виртуальных машины @ 2 vcpu под управлением PM2 ( будет 4 запущенных экземпляра игры)
  2. Разъем.сервер ввода — вывода-2 виртуальных машины @ 2 vcpu под управлением PM2 ( будет 4 запущенных экземпляра сокета.сервер ввода-вывода)
  3. Сервер Redis ( в зависимости от нагрузки вы можете захотеть иметь 2 отдельных экземпляра, один для сеансов и игровых элементов, а другой для управления socket.io )
  4. Хранилище объектов (S3 или другое хранилище объектов) для хранения изображений
  5. Дополнительный CDN

С Розеткой.io вы наверняка захотите использовать redis.socket.io НПМ. Это позволит вам масштабировать сокет.ввод-вывод в несколько отмеченных, пакет redis для сокета.io управляет подключенными клиентами, поэтому, даже если пользователь подключен к другому серверу сокетов, он все равно сможет отправлять и получать сообщения

Не уверен, где вы размещаете сейчас, но доступно множество сервисов, и в зависимости от того, насколько вы хотите управлять, вам, возможно, захочется взглянуть на такие сервисы, как «приложения» из digital ocean. Это в основном услуга «CAAS», где вы можете подключить свой сокет.сервер ввода-вывода в GIT, а затем разверните его в работающем контейнере, DO будет выполнять балансировку между каждым из ваших запущенных «приложений», чтобы вы могли по требованию масштабировать запущенные экземпляры вверх и вниз по мере необходимости. Это не самый дешевый, хотя и имеет некоторые недостатки с точки зрения пропускной способности и т. Д., Но это хорошо, если у вас есть известные всплески, которые позволяют вам масштабироваться вверх и вниз и т. Д.

Комментарии:

1. Большое вам спасибо за это замечательное объяснение, но если я могу спросить, почему сервер узлов и сервер сокетов не совпадают. И будет ли этот архитектор обрабатывать каждое событие в одной и той же комнате синхронно или каждый экземпляр сервера может обрабатывать другое событие для одной и той же комнаты(при условии, что пользователи комнаты подключены к разным экземплярам)?

2. Нет никаких причин, по которым они не могут находиться на одном сервере, просто когда вы думаете о масштабе, было бы более эффективно разделить их, если у вас есть веб-приложение «узел» и сервер сокетов. Если есть только приложение узла, то нет необходимости в другом приложении узла. Для эвенов и комнат это то, где розетка. io redis будет использоваться для обработки отправки событий всем пользователям, независимо от того, к какому серверу они подключены. Таким образом, отправка в room1 сообщит всем кластерным серверам сокетов о необходимости отправки в room1 во всех экземплярах

3. Огромное спасибо. Я действительно ценю это !!