NodeJs-кластер с Socket.IO и пространствами имен

Я создаю браузерную игру. Прототип готов, и теперь я думаю, как его масштабировать и разместить. У меня уже есть игровой сервер, который в настоящее время обрабатывает одну игровую сессию. Игровая сессия состоит из соединения socketio с 8 игроками (максимум).

Я хотел бы использовать, например. Node-Cluster, чтобы иметь несколько игровых серверов в одном док-контейнере, в котором каждый игровой сервер должен обрабатывать одну или несколько игровых сессий, чтобы можно было использовать все ядра процессора. Игровая сессия используется только 8 игроками, и игровые сессии должны быть изолированы друг от друга.

Насколько я знаю, Node-Cluster позволяет мне использовать один и тот же порт для всех подпроцессов. Я подумал о том, чтобы иметь пространство имен для каждой игровой сессии (например, идентификатор в браузере, к которому все равно подключаются игроки. Цель: вы получаете URL-адрес, который вы отправили другу, чтобы пригласить его, например, skribble.io - https://localhost/?gameid=1234). Так что в моем случае присоединение к пространству имен в основном такое же, как присоединение к игре.

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

поэтому в итоге должно получиться следующее:

 GameServerMaster [Maps ids to processes like: [ClusterNode1:[id1,id2,..]}
   - GameServerClusterNode1
     - GameSession1 [id1 io.off("/id1")]
     - GameSession2 [id2 io.off("/id2)]
     - ....
   - GameServerClusterNode2
     - GameSession3 [id3 io.off("/id3")]
     - GameSession4 [id4 io.off("/id4)]
     - ....

Я нашел socket.io-redis, но это кажется немного перегруженным, потому что трансляции нет - каждая игра изолирована. (а также я не хочу размещать Redis только для этого варианта использования)

Кроме того, я нашел sticky-session, но, используя это, я не знаю, как перенаправить входящее соединение на правильный процесс, я думаю, что это просто балансирует нагрузку, что плохо, потому что оно должно быть перенаправлено на тот, который фактически обрабатывает запрошенную игровую сессию - но я думаю, что мне все равно нужно что-то подобное, или я?

Является ли то, что я делаю (или планирую сделать), правильным подходом? Есть ли у вас какие-либо предложения с точки зрения технологии или архитектуры?

Не лучше ли выбросить всю часть кластеризации и просто сделать так, чтобы док-контейнер обрабатывал один узел, который обрабатывает эти несколько игровых сессий?


person mick    schedule 15.11.2020    source источник


Ответы (1)


Я оказался в такой же ситуации, и я пришел к следующему решению.

Идея:

Вы создаете новый процесс с модулем кластера на другом порту. А с мастер-процессом вы действуете как роутер.

Пример:

Before player joins a room, he asks the router,
(broadcast) where is room 123. The router asks his subprocesses
which of them hosts room 123, and forwards the result (eg. port 3001)
 to the client. The client then connects to the exact process. 

Проблемы:

If more than one subprocess has the same roomId, there will be a conflict, 
but I guess you will figure out a way to avoid this, 
even tho the probability for this to happen is very low.

Обратите внимание, что это решение предназначено для использования всех ядер вашего компьютера, но не является решением для распространения на несколько компьютеров.

Если вы хотите распространить его на несколько машин, вам следует пересмотреть свой выбор на Redis.

person Liki    schedule 20.11.2020
comment
Спасибо за ваш комментарий. я тоже думал об этом, но я также думал, что открытие диапазона портов в контейнере докеров будет просто результатом плохой архитектуры, особенно когда node-cluster предоставляет функцию совместного использования портов. но я предполагаю, что это, вероятно, все еще самое надежное решение, потому что оно не требует дополнительных зависимостей. - person mick; 29.11.2020