Anubis
@Anubis
Люблю корейскую кухню и веб-разработку

Игровой сервер на node.js, используя cluster и redis, какую логику использовать?

Всем привет. Прошу у опытных коллег помощи в деле организации логики игрового сервера — на новой для меня платформе, из-за чего от недостатка практического опыта (за спиной тривиальнейшие браузерки на php-mysql-memcache) очень не хотел бы напортачить с точки зрения оптимизации, дабы потом не пришлось «на лету» переформатировать логику.

Цель — написать браузерку с «комнатной» пошаговой боёвкой (а-ля jrpg), где каждый игрок «отвечает» за своего персонажа. В качестве серверной платформы остановился на node.js, базой данных будет служить redis с orm jugglingdb. Общение с клиентами через tcp-сокеты.

Игрокам, участвующим в битве, сервер по очереди выдаёт право хода, ограничивая выбор применяемого удара/вещицы/скилла игроком заданным интервалом (допустим, 20 секунд), затем выжидает определённый интервал времени (в зависимости от длительности анимации того или иного действия активного персонажа, прописанное в базе сервера), после чего выдаёт право хода следующему игроку.

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

Пробуксовку в деле проектирования логики вызывает принципиальное желание задействовать cluster с целью выноса части обрабатываемых задач в параллельно запущенные worker'ы, подняв потолок производительности по сравнению с работой всей логики внутри одного процесса на одном ядре.

Какого рода задачи разумно вынести из главного процесса в «воркеры»? В голову приходит только подключение сокетов и общение с ними. Про redis, точнее про его функционал publish/subscribe, тоже хотелось бы узнать в плане производительности — подойдёт ли он для общения между потоками и мастер-процессом, или лучше организовать это через process.on('message') / worker.send(data)?

Такого рода данные как объекты боевых комнат и лобби сбора игроков предполагаю хранить в главном процессе. Возможно, есть техники лучше?

Буду очень признателен за любые советы, объяснения и примеры.
  • Вопрос задан
  • 3161 просмотр
Пригласить эксперта
Ответы на вопрос 2
evnuh
@evnuh
Поиск Гугл помог мне, впусти и ты его в свой дом
Делать по потоку на коннект - худшая идея.
Использовать редис для межпроцессорной коммуникации - хорошая идея.
Как разбить задачи по воркерам. Думаю, отличным вариантом будет равномерно всё размазать на все ядра, то есть, главный поток выступает неким роутером, который по очереди раздаёт (по очереди воркеры сами забирают) себе инфу пришедшую по сокету в главный процесс. При этом всё можно разбить по игрокам, а привязывать на каком из поток обрабатывается какой игрок по его id, например. Для всего этого можно использовать редис, но лучше не поленитесь и хотябы чуточку почитайте про zeromq, там и сокеты, и concurrency framework и message passing.
Ответ написан
alexclear
@alexclear
A cat
> Какого рода задачи разумно вынести из главного процесса в «воркеры»? В голову приходит только подключение сокетов и общение с ними.

Зачем Вам в этой схеме "главный процесс"? Для решения Вашей задачи достаточно запустить нужное количество воркеров (допустим, у Вас на машине 8 ядер - запустите 9 воркеров) на разных портах и поставить HAProxy в качестве балансировщика перед ними в TCP режиме. Правда, при этом у Вас будет теряться информация об IP-адресах клиентов, так как соединения терминируются на HAProxy, а в TCP режиме он сведения о клиентском IP на бэкенд не передает. Не беда - Вы можете использовать HTTP/1.1 и web sockets для решения Вашей задачи, тогда из заголовка X-Forwarded-For на бэкенде можно будет узнать адрес клиента.
Второй вариант более сложный - действительно, используйте мастер-процесс, порождающий нужное количество воркеров заранее. Схема хорошо описана здесь, и там даже приведена картинка, отличие Unicorn от Вашей схемы в том, что воркеры Unicorn работают синхронно, а Ваши будут работать асинхронно.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы