Масштабирование сервера по горизонтали

У меня есть вопрос по поводу масштабируемости. Допустим, у меня есть многопользовательская игра, такая как Uno, где сервер обрабатывает все. (Предположим, что это текстовая игра для простоты). Например, чтобы получить информацию, распечатанную пользователю на клиенте, сервер может отправить PRINT string, или же CHOOSE data (выбрать карту для игры) и т. д. В этом отношении клиент "тупой", а сервер обрабатывает игровую логику.

Быстрый пример того, как это может работать на уровне протокола:
Сервер отправляет: PRINT Choose a card
Сервер отправляет: CHOOSE Red 1,Blue 1 (пользователь показывает кнопку или что-то и выбирает красный 1)
Клиент отправляет: Red 1

Допустим, у меня есть эта архитектура:
Класс игрока: хранит карты, которые есть у пользователя, возможно, некоторые методы (например, tellData(String data) который отправит данные PRINT, sendPM() который может личное сообщение пользователя)

Класс сервера: выполняет аутентификацию, позволяет пользователям создавать новые игры, показывает пользователям список игр, к которым они могут присоединиться

Класс игры: обрабатывает пользователей, играющих в карты, управляет переключением на нового игрока в свой ход, вызывает методы класса игрока, такие как tellData(), pickCard(), так далее

Как бы я масштабировал это, чтобы запустить сервер на нескольких компьютерах? В настоящее время все пользователи подключаются к одному серверу и требуют взаимодействия классов Player, Server и Game друг с другом. Если бы кто-то мог дать некоторые предложения и / или указать мне на некоторые хорошие ресурсы / книги по этому вопросу, это было бы очень ценно (нет, это не домашнее задание или что-то для бизнеса, это всего лишь личный проект и любопытство мой). С точки зрения масштабируемости, я хотел бы просто иметь возможность добавить еще один сервер и справиться с дополнительной нагрузкой игроков - но наиболее одновременных соединений будет 1000.

Кроме того, станет ли это значительно более сложной задачей масштабируемости, если мы добавим больше игр?

Кроме того, каков наилучший способ хранения игровых данных? В базе данных SQL или сериализации объектов, или что? Под этим я подразумеваю, скажем, 3 пользователя находятся в игре Uno и хотят вернуться к ней позже. Я не хочу вечно хранить свои карты и информацию об игре в классе Player/Server/Game (RAM) - я хочу где-то выкинуть это, поэтому, когда пользователь входит в систему, информация может быть загружена, однако это было сбрасывается в оперативную память, а затем соответствующие объекты Player/Game.

Наконец, как я могу внести изменения в сервер без необходимости убивать его и перезапускать? Предположим, что сервер был написан на Java или Python.

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

Спасибо за любую помощь!!

РЕДАКТИРОВАТЬ: Есть какие-нибудь хорошие книги или разговоры, которые вы все порекомендовали бы по этому вопросу?

1 ответ

1. Масштабируемость: включает в себя архитектуру приложения для нескольких экземпляров сервера, сеанс реплицируется / совместно используется и сбалансирован по нагрузке. Вы можете реализовать архитектуру очереди сообщений (rabbitmq) / ESB (корпоративная служебная шина) для своего приложения.

2. Простота масштабирования: зависит от развертывания и выбранных вами серверов.

3. Сопротивление: игра для человека предполагает его конкретное игровое состояние в любой момент времени. Если вы можете представлять информацию о состоянии семантически, вы можете хранить данные в файлах сохранения разметки или сохранять информацию о состоянии непосредственно в БД. В противном случае вам может потребоваться сериализовать объекты и сохранить их в файловой системе / как BLOB-объект в БД на случай, если пространство состояний огромно.

4. Горячее развертывание: JVM в большинстве случаев всегда будет нуждаться в перезапуске для перезагрузки файлов классов, поэтому на стороне сервера Java вам всегда нужно будет перезапускать. В Ruby/Rails определенные части приложения могут быть развернуты в горячем режиме. Если вам нужно 100% горячее развертывание, возможно, Erlang - это ответ.

Для улучшения параллелизма вы также можете использовать четные архитектуры серверов / приложений: thin/eventmachine для ruby ​​или apache mina, jboss netty для java.

Другие вопросы по тегам