Кластеризованный игровой сервер на Java: реально ли?
Привет! Недавно пересел с Python (web) на Java. И понял, что мне хочется заняться чем-то более классным, нежели веб. Осмотрелся вокруг, вспомнил пример некогда популярного Minecraft. Вспомнил его ужасный сервер, вспомнил попытки его оптимизации (которые закончились его переписыванием) проектом GreenCubes, и подумал: а почему бы не написать свой Minecraft c блекджеком и дамами? Да, я понимаю что minecraft (и его идея) уже давно пережил пик популярности. Да, я понимаю, что у меня, вполне вероятно, не получится ничего путного. Нет, я не собираюсь открывать свой сервер minecraft. Это просто учебный проект.
В общем, основная идея в том, чтобы сервер динамически "размазывался" по некоторому числу нод при необходимости. И чтобы при этом мир для игрока оставался цельным.
То есть сервер построен так, что при повышении нагрузки он отделяет некоторый кусок мира и перемещает его на другую ноду, незаметно переключая туда клиентов, находящихся в этом куске. При падении нагрузки на некоторое время - объединение мира. Одна нода умирает, соседняя подхватывает себе ее клиентов. Ну и тоже самое при простых путешествиях игрока по миру: его просто перебрасывает между нодами..
В качестве клиентской библиотеки посматриваю на jmonkeyengine. Потому как именно на нем GreenCubes писали свой клиент, схожий с minecraft. И получилось не так уж и плохо.
А вот что делать с сервером - неясно. В качестве сетевой библиотеки смотрю в сторону netty. Пока не знаю, что использовать в качестве базы для протокола общения с клиентом. И самое главное, не очень представляю при помощи чего реализовать распределенное хранение мира, как организовать бесшовный перенос игрока со стороны сервера. В общем, джависты, помогайте советом. В какую сторону смотреть?
Это просто идеальная задача для Akka.
Сообщения - простая сериализация поверх protobuf, отказоустойчивость и балансировка с роутингом, кластеризация - все это из коробки.
Можно сделать единую точку входа на netty, если не будет справляться можно решить вопрос dns балансировкой и поднятием еще 1 инстанса. А уже дальше от netty делегировать событие по координатам другой ноде. Тем самым достигнув разбиения по квадратам. Проблемы будут, когда все будут в одном месте, но и это тоже теоретически решаемо добавлением инстансов для куска карты. В общем задача не из легких, дабы не было простоев нужно подходить к вопросу балансировки очень хорошо.
В общем смотрите в сторону netty+akka или netty+spring reactor
Пожалуй, единственная точка входа не вариант. Потому как клиент должен иногда быть подключен сразу к нескольким соседним нодам. Для бесшовного перехода. В этом случае на клиенте нужно иметь как минимум список ближайших нод.
Хотя с другой стороны можно заставить сервер ретранслировать некоторые события с соседней ноды. Это позволит сэкономить некоторое количество соединений. И проблему с глобальным я том это тоже решает. Но тогда каким образом доставлять такие события? Через брокер сообщений? Мне кажется, это не очень хорошо.
rdvlip: Вы не совсем меня поняли. Netty будет в себе хранить всю инфомацию о backend серверах и осуществлять балансировку, не более. Все остальная логика будет к примеру на akka серверах. Брокер сообщений вам в любом случае понадобится, другое дело какой. jms вам однозначно не нужен, но через akka делегировать обработку другому серверу можно легко. Такие вещи нужно делать асинхронными всегда)