Привет! Представляю вашем вниманию перевод статьи "Why you should run your game servers independently from your chat" Joe Hanson.
Разработчики многопользовательских игр часто сталкиваются с дилеммой:
- Использовать уже существующие игровые серверы (на которых, непосредственно, работает игра) для обеспечения функциональности чата
- Использовать отдельные сервера для реализации функциональности чата
В конце – концов, это ведь просто чат, так? Маленькие сообщения передаются от пользователя к пользователю/небольшой группе пользователей, вот и всё. Так почему бы просто не добавить немного функционала на уже работающие серверы? Что может пойти не так?
Хотя на первый взгляд это решение может показаться неплохим, в связи с ним может возникнуть ряд проблем. Ниже мы поговорим о том, почему вам стоит разделять игровые сервера и различные социальные фичи (особенно чат). Это разделение позволит нам улучшить производительность и масштабируемость игры, вместе с тем дав нам возможность с лёгкостью добавлять новые «социальные» фичи» и расширять их функциональность в будущем.Подробнее — под катом.
Микросервисы делают игру более управляемой
Микросервисно-ориентированная архитектура разбивает большое приложение, в нашем случае — игру, на небольшие модульные, изменяемые независимо друг от друга сервисы (службы), взаимодействующие друг с другом через простые общедоступные API. Такой подход обеспечивает лёгкость добавления нового функционала и поддержку уже существующего.
Отделение игровых серверов от функциональности чата делает всю инфраструктуру приложения более управляемой и приближает нас к полностью микросервисно-ориентированной архитектуре. Давайте детальнее посмотрим на внутриигровой чат и его «взаимоотношения» с игровыми серверами, обеспечивающими основную функциональность игры.
При использовании «монолитной» архитектуры команда разработчиков оказывается ограниченной одним стеком технологий – одними и теми же языками программирования, базами данных и окружениями разработки, с помощью которых уже написана игра. Включение в команду новых программистов или внедрение новых технологий реализуется гораздо проще и быстрее при микросервисном подходе к архитектуре.
Зависимости также становятся гораздо более заметными на монолитных архитектурах. Поломка единственной функции приложения может привести к нерабочему состоянию всей игры. Разделение игры на микросервисы облегчает изоляцию и фиксы багов в любом отдельном модуле.
Основное назначение игровых серверов (с которым они хорошо справляются, или, по крайней мере, должны хорошо справляться) состоит в синхронизации и передаче игрокам информации о передвижениях и состоянии игроков в реальном. Технологии, используемые на игровых серверах для достижения этих целей, вряд ли являются лучшим решением для реализации чата. Разделённые компоненты, как уже было отмечено, более удобны в поддержке и независимом масштабировании.
Рисунок, приведённый выше, иллюстрирует инфраструктуру игры, в которой чат и игровые серверы существуют отдельно друг от друга.
Помимо чата, можно также добавить другие сервисы, существующие отдельно от игровых серверов, такие как: авторизация, статистика, информация о лучших игроках и т.д.
Обеспечение бесшовного игрового опыта и эффективной работы чата
Производительность игры в целом является очень важным фактором для многопользовательской игры. Медленная скорость работы игры приведёт к неминуемой потере игроков. При использовании монолитной архитектуры, игра может показывать неплохую производительность на этапе тестирования, но в боевых условиях с большим количеством настоящих игроков, разбросанных по всему миру и обменивающихся информацией на огромной скорости быстро проявляются лаги и увеличение задержек как со стороны чата, так и со стороны, собственно, игры.
Разделение чата и игровой логики обеспечивает наиболее эффективное использование процессорных и сетевых ресурсов. Основная задача игровых серверов состоит в обеспечении «бесшовного» (с минимальным количеством лагов/задержек) игрового опыта для каждого игрока. Таким образом, вычислительные мощности серверов должны быть использованы для достижения максимальной производительности игры.
Допустим, у нас есть игра жанра battle arena – например, LoL или EVE Online. Мы хотим обеспечить возможность одновременной игры нескольких сотен игроков в одном игровом мире. Это — тысячи сообщений, представляющих собой информацию обо всех действиях игроков, пересылаемых через игровые сервера в реальном времени. Добавим сюда ещё и сообщения чата. Вполне возможно, что некоторые игроки будут спамить в чат, чтобы специально замедлить скорость работы игрового сервера (на плечах которого будет лежать как передача информации об игровом мире, так и передача сообщений чата). Конечно, возможно отлавливать таких игроков и, например, блокировать для них чат, но для этого всё равно потребуется выполнять дополнительные вычисления на игровых серверах, съедая, таким образом, часть ресурсов, которые могли бы предназначаться для игры.
Игровой сервер и так нагружен разнообразными расчётами, связанными с физикой, графикой и звуком. Добавление функциональности отправки сообщений — от игрока к игроку/группе/команде, их парсинга и маршрутизации — всё это постепенно усложняет инфраструктуру приложения и приводит к ухудшению общей производительности игры.
Попытка запустить каналы чата отдельно от каналов многопользовательской игры приведёт к потере ценной вычислительной мощности, которая могла бы быть использована для реализации сложных игровых механик вместо решения проблем маршрутизации сообщений чата.
UDP vs. TCP: Когда нужны оба, а когда достаточно одного?
Перейдём к вопросу о выборе между протоколами UDP и TCP для реализации онлайн игр. Какой же из них лучше выбрать в той или иной ситуации?
Динамичные многопользовательские игры (шутеры, MOBA и т.п.) используют протокол UDP для синхронизации передвижений игроков и обновления состояния игры. UDP идеально подходит для обмена отправки этой информации на очень высокой скорости, но он не гарантирует надёжной доставки сообщений и их поступления в правильном порядке.
Протокол TCP гарантирует доставку сообщений, что делает его идеальным выбором для реализации чата. Можно добиться прекрасной производительности, если сама игра будет использовать протокол UDP, а различные социальные фичи — протокол TCP.
В играх, не отличающихся высокой динамикой (таких, как пошаговые стратегии), TCP, благодаря своей высокой надёжности, может оказаться подходящим вариантом для реализации как чата, так и игровой логики. Конечно, при этом никуда не девается необходимость разделения игровых серверов и чат-серверов. Особенно, когда игра становится популярной и в неё начинают одновременно играть тысячи игроков.
Задержка также является элементом, требующим внимания, так как стандарты, определяющие допустимые задержки для функционала самих многопользовательских игр и задержки для социальных фич (вроде чата) различаются. Для многопользовательской игры (включающей синхронизацию состояния игры между игроками и передачу информации об одних игроках другим игрокам) задержка не должна превышать 20 миллисекунд, в то время как для приложений чата допустимая задержка составляет 250 миллисекунд.
Таким образом, у нас есть два типа обмена сообщениями в реальном времени с различными стандартами. Если они будут работать независимо друг от друга, мы легко сможем изменять реализацию каждого из них, основываясь на соответствующих требованиях.
Расширяемость функционала чата
Поддержка чата как standalone-приложения и выбор для этого стандартного промышленного протокола (например, XMPP или WebSockets) или с помощью удалённой службы (например, PubNub) открывает возможность с лёгкостью добавлять новые социальные фичи.
Для начала, достаточно реализовать базовую функциональность чата (достаточную для обмена сообщениями). Реализовав базовую инфраструктуру для чата, позднее мы сможем начать её расширять.Понемногу добавляя код, мы можем с лёгкостью добавить различные дополнительные функции чата, такие как: индикатор того, что игрок печатает; индикатор присутствия пользователя в сети; счётчик непрочитанных сообщений и другие полезные фичи, которые игроки обычно ожидают от чата.
Заключение
Большие и маленькие компании, занимающиеся разработкой игр (включая Pocket Games и EVE Online) постепенно переходят (или уже перешли) на эту архитектуру. Начиная с масштабируемости и высокой производительности и заканчивая свободой внедрения новых технологий (без необходимости запираться внутри одного стека), преимущества очевидны: разделение чата и игровых серверов — путь, которым стоит идти.
Автор: Romanovsky