Постарайтесь сделать это как можно более простым, чтобы интерфейсы были четко определены и задокументированы. Обслуживание и отладка сложной системы в производстве легко превращается в ад. Поэтому, если есть простой и сложный подход, подумайте дважды, прежде чем переходить к сложному.
Определение услуг
Я думаю, что первым шагом является определение сервисов и их зависимостей : статический контент, аутентификация, локальный чат, глобальные каналы чата, региональные каналы чата, список друзей, гильдии, сумка / инвентарь, аукционный дом, глобальная карта, мир, ...
Затем для каждой из этих служб решено, может ли клиент поговорить с ними напрямую. Например, довольно просто позволить клиенту общаться напрямую с серверами, отвечающими за глобальные каналы чата. Мировые серверы вообще не должны участвовать в сообщениях чата. Региональный чат может быть реализован таким же образом, но мировые серверы должны сообщать серверам чата, когда игроки меняют регионы. Опять же, они не должны заботиться о сообщениях.
Третий шаг - подумать о балансировке нагрузки в сервисе . Например, глобальные и региональные каналы чата могут быть разделены на несколько серверов в зависимости от их имени. Вероятно, неплохо бы не жестко кодировать этот раздел на клиенте, а предоставлять сервис поиска.
Мировые серверы
Самой сложной частью обычно являются мировые серверы , поэтому я начинаю с простого подхода. Вероятно, хорошей идеей будет позволить клиенту напрямую общаться с сервером, ответственным за регион, в котором он находится. Поэтому при входе в систему или при пересечении региона клиенту необходимо сообщить, к какому серверу подключаться.
Простой подход - разделить мир на независимые регионы . Под независимыми регионами я имею в виду, что игрок не может смотреть из одной части в другую, а монстры не могут пересекать части. Эти регионы отличаются от регионов, которые игрок видит в зависимости от ландшафта и истории внешнего мира. Обычно большинство монстров находятся в подземельях, и игроки склонны признать, что им нужно пройти через ворота, чтобы войти в подземелье. Особенно, если эти подземелья создаются для каждой группы игроков. Другими примерами во внешнем мире являются разные континенты и долины, окруженные высокими горами.
Подход непрерывного мира действительно быстро становится сложным, поэтому имеет смысл хорошо его спланировать: какая информация нужна клиенту? Какой информацией должны поделиться серверы? Игрок в основном будет взаимодействовать только с объектами (включая монстров и NPC) в том же регионе. Вы можете обмануть, разместив объекты вне диапазона кликов от границы зоны. Это означает, что клиент больше всего интересуется информацией только для чтения для соседних зон. В этих случаях серверам зон не нужно ничего координировать, за исключением проверки разрешений, что игрок находится достаточно близко, чтобы подключиться к соседней зоне.
Это оставляет лишь очень небольшое количество сложных случаев, когда объекты или действия должны пересекать границу сервера. И это хорошо, потому что такие случаи, как стрелки и заклинания, критичны для производительности. Это может быть хорошей идеей разделить бой на атакующих и обороняющихся. Таким образом, сервер заклинателя будет определять параметры атаки, включая положение заклинателя. Сервер защитника получит сообщение об атаке и рассчитает удар. Серверу злоумышленника не нужно знать о воздействии; клиент узнает об этом, используя свое соединение только для чтения.
В зависимости от того, насколько сложна модель вашего плеера, может потребоваться пара секунд, чтобы перенести ее на другой сервер (у Second Life есть огромная проблема с этим). Эту проблему можно решить, подготовив передачу заранее, когда игрок приблизится к виртуальной границе. Таким образом, большая часть данных игрока уже кэшируется на конечном сервере, когда происходит фактическая передача обслуживания.
Резюме
Разделите проблему, определив различные сервисы, которые могут быть распределены по серверам с небольшими зависимостями. В качестве следующего шага рассмотрим, как выполнить балансировку нагрузки в критически важных сервисах. Делегируйте балансировку работы клиенту, указав ему подключаться напрямую к соответствующим серверам (очевидно, серверы должны проверять разрешения). Сохраняйте это как можно более простым, хорошо документируйте обязанности различных служб и серверов, предоставьте возможность включить отладочный вывод.
PS: некоторые из этих методов могут быть использованы для повышения надежности. И вы должны помнить об этом, потому что использование многих серверов подразумевает гораздо более высокий риск взлома; не только в программном обеспечении, но и на аппаратном уровне.
Обычно мир делится на несколько небольших регионов. Каждый из этих регионов обычно является независимым серверным процессом (мировые серверы WoW или узлы Eve's Sol) и может работать на любом из нескольких компьютеров. В некоторых играх есть явные границы между картами (Eve, STO, Guild Wars), в то время как другие пытаются маскировать это больше (WAR, Free Realms). Те, кто выбирает более плавный подход, обычно обнаруживают, когда вы приближаетесь к границе между двумя серверами, и два процесса согласовывают передачу обслуживания. Лучшее место, чтобы, вероятно, искать описание этого, - как вышки сотовой связи выполняют передачу обслуживания мобильных телефонов. Если загрузка одной карты (Jita, Ironforge, Earth Space Dock) становится действительно большой, иногда вы можете перенести отдельные функции на другие серверы (AI, некоторые части управления игроками), но это либо должно быть встроено с самого начала, либо потребуется серьезная модернизация. Почти всегда выгоднее просто купить лучшее оборудование, чтобы посвятить себя тем немногим картам.
источник
Это, вероятно, не так часто, как вы думаете; по крайней мере, если вы думаете, что один цельный мир управляется несколькими серверами одновременно.
Не считая абсолютно отдельных шардов, есть 2 направления, в которых вы можете разделить онлайн-игру, которую можно считать «горизонтальной» и «вертикальной»:
Очевидно, что эти подходы ортогональны, и вы можете объединить их. Фактически, почти обязательно иметь отдельный сервер базы данных, очень распространенный способ отталкивать вход / авторизацию на отдельную машину от игрового процесса, а также все более распространенный способ использовать ферму вне чата и других некритических коммуникаций, независимо от того, каков игровой мир. делится
Но в целом, когда есть географическое разделение, большинство игр не позволяют вам взаимодействовать через эти границы, потому что это трудно сделать хорошо. Вместо этого они прибегают к другим способам заставить вас выглядеть так, будто вы все еще в одном и том же шарде и на одном сервере, хотя на самом деле это не так. например. - загрузка экранов или других анимаций, которые скрывают смену сервера при переходе между зонами или с одного континента на другой. - отдельные подземелья или рейды, которые изолированы от всех остальных. Они похожи на осколок внутри осколка и могут легко запускаться на отдельном сервере, что помогает сбалансировать нагрузку.
Я не могу говорить авторитетно о WoW, но я предполагаю, что они делают почти все вышеперечисленное: создание экземпляров, отдельные географические области, которые не могут взаимодействовать, соединенные какими-то порталами, отдельные серверные и аутентификационные серверы. Я слышал, что в сферах WoW в одной и той же области одновременно может быть от 1000 до 10000 игроков, что легко можно осуществить с помощью описанных выше схем.
Но давайте предположим, что у вас есть один огромный мир, и вам нужно разрешить игрокам один сервер взаимодействовать с игроками на соседнем сервере. Это легко сделать в теории - во-первых, серверы должны взаимодействовать для совместного использования деталей объектов вдоль границ (поэтому объект на одном сервере может иметь прокси-представление на другом), а затем просто изменить всю свою логику на передачу сообщений с помощью сообщения, перенаправляемые из прокси-сервера обратно в официальный источник, где это необходимо. Сообщения могут передаваться между серверами или внутри сервера довольно прозрачно, поэтому один подход подходит для всех систем.
Проблема здесь в том, что ранее простая логика может стать очень сложной при переводе в сообщения, например. сделка с двумя игроками, которая может происходить безопасно и атомарно, когда оба игрока находятся на одном сервере, становится более длительным процессом, когда сообщения должны отправляться взад и вперед, проверяться при каждой отправке и вводиться меры предосторожности, чтобы гарантировать, что один игрок не сможет использовать другой, изменяя торговлю, пока сообщение путешествует. Вы даже не можете предположить, что другой игрок все еще будет существовать ко времени прибытия сообщения (поскольку они могут умереть, выйти из системы и т. Д.), Поэтому код становится очень сложным. И это будет применяться практически к любой системе, в которой 2 или более объекта могут взаимодействовать или сотрудничать - торговля, бой, группировка, аукционы, совместное использование добычи, обучение и т. Д.
Эти проблемы не являются непреодолимыми, но для большинства игр их слишком сложно попробовать, если вы можете разделить нагрузку с помощью других средств и сохранить всю игровую логику на одном сервере. Таким образом, почти все современные игры идут по этому пути.
источник
Существует много методов балансировки нагрузки на MMO-сервере, поскольку существует достаточно широкий диапазон обрабатываемых данных. Я предпочитаю метод дерева бина процесса.
Глобальный сервер передает пользовательские соединения в бункер процессов, который может обрабатывать несколько пользователей одновременно. бункеры процессов выполняют всю сложную обработку и отвечают на глобальный сервер только данными, которые имеют глобальное значение, такими как глобальный чат и позиционирование. Этот метод балансирует намного лучше, чем серверы регионов, так как регионы могут сильно различаться по населению, в то время как общая пользовательская обработка достаточно различна, так что она должна естественным образом сбалансировать себя по большей части.
Просто выполните некоторую базовую балансировку нагрузки через глобальный сервер, чтобы, когда корзина процессов достигла определенного использования памяти / процессора, вы запустили новый сервер корзин процессов.
источник