ч.15 Игровой авторитарный сервер на процессах и его архитектура в картинках — Создание сервера для онлайн ММО игр на PHP
В предыдущей статье я рассказывал об архитектуре приложения, где ее отдельные компоненты могли бы работать параллельно не блокируя выполнения друг друга.
В этой статье я расскажу о причинах, по которым пришлось выбрать не многопоточное, а мультипроцессорное взаимодействие для разрабатываемого сервиса создания авторитарных серверов (http://mmogick.ru) и выделить компоненты в сервисы.
Бонус - архитектура игрового сервера в картинках в конце статьи.
Причина 1 - пользовательский код
Я рассказывал о том, что для вашей игры, где все механики рассчитывает сервер нужна возможность добавлять свой код в каком то toolset, не углубляясь во весь Фреймворк в целом и не изучая его архитектуру. Однако в будущем это может понадобиться и нам понадобиться менять и его.
Так как сервис, в том числе и SAAS (облачное) решение то нужно ограничить возможность пользоваться опасными функциями (например для доступа к файловой и операционной системе машины где работают и другие пользователи сервиса), для этого нужно ограничить вызов таких функций, ограничить потребление CPU и памяти, что и делается для определённого процесса.
Это может быть и код на JS, LUA и в тч на PHP - нужен именно скриптовый язык что позволит просто и быстро добавлять и менять фичи, притом сам сервер может быть написан совершенно на другом компилируемом языке (так устроено во многих онлайн играх с авторитарным сервером, для того что бы НЕ перекомпилировать каждый раз все целиком и часто у издателей, что платят авторам игр ежегодный royalty (авторский гонорар) нет доступа к исходному коду. но есть к таким скриптам).
Ниже приводиться список небезопасных и "нежелательных" встроенных функций для пользовательского кода языка PHP
а так же классы
Причина 2 - сервисная архитектура
По определению сервис - это часть какого-то приложения которая может быть написана на любом языке (в т.ч. отличного от языка приложения) и работать с ним в паре (как например различные GO сервисы с вебсайтами, например для обменов с 1с и т.п). Когда пишется приложение на потоках (thread) то оно тесно повязано на языке (вы разветвляете свой код как бы на 2 под процесса).
В игровом сервере есть несколько основных компонентов (у разных проектов свой, приведу на базе http://mmogick.ru)
- WebSocket сервер - принимает и отправляет пакеты, про игру он не знает ничего
- Игровой сервер - загружает из БД данные введенные в админ панели (загруженные карты, данные игроков, npc, анимации) для отправки в сервис WebSocket на отправку игрока и сохраняя изменения и запуская игровой кадр сервиса ниже...
- Песочница (сервер Game механик) - это тот процесс в котором выполняется пользовательский код добавленный через админ панель. Здесь происходят расчеты текущего кадра: физики, поиска путей, что какой npc в этом кадре делает (двигается, регенерирует, атакует и т.д.)
Итого 3 процесса для запуска одной карты. Карт может быть много и они могут быть физически на разных серверах при этом визуально это будет открытый мир онлайн игры (о такой архитектуре я рассказывал в другой статье).
Функциональное наполнение разделов этих сервисов выглядит следующим образом (весь код и примеры разделов доступны по гостевому доступу на сайте проекта)
Причина 3 - шина данных для взаимодействия
Когда вы пишете код на потоках язык программирования предоставляет вам инструмент синхронизации (обмена) данными между этими потоками ("субпроцессами"). В C# это происходит между общими статическими свойствами (которые в том коде, где вы делите потоки), в GO и PHP этот инструмент называется Channel (обмен происходит через общую оперативную память Shared Memory). Однако сервис как я писал раньше это независимое от языка приложение (например мы захотим сделать WebSocket сервер не на PHP а на GO) и нужен уже независимый от языка инструмент обмена данными между приложениями, в т.ч. написанных на разных языках.
Ниже привожу примеры инструментов с замерами скорости обмена данных в секунду на малых пакетах (забегая вперед скажу что был выбран популярны метод обмена IPC очереди)
Для примера хотел бы поделиться ранней версией архитектуры игрового авторитарного сервера на потоках которую я разработал (тем не менее многие вещи из этой диаграммы используется и по сей день)
В заключении
Для тех кто читает серию статей и следит за проектом я подготовил ответ из предыдущей статьи "как ускорить ваш TCP сервер в 2 раза отключив лишь один стандартный параметр".
Ответ на этот вопрос пришел в Южной Африке с ужасным ping - приходилось отключать все обновления, авто скачивание медиа файлов в мессенджерах ... В общем мой компьютер стал очень редко стать какие-то запросы в сеть и я обнаружил, что работая в игровом движке Unity (использует C#) пакеты отправляются не сразу... При этом в версии для WEB (браузерные) такой проблемы нет.
Описание проблемы можно увидеть ниже
Решение на 2:00, а причина параметр TCP взаимодействия в netFramework NoDelay = false. При работе с PHP этот параметр так же выключен, а в JS наоборот включен - он НЕ отправляет пакеты сразу как они приходят в очередь, а ждет еще некоторое время для отправки пакетов пачками далее по стеку в сетевую карту для минимизации времени задержки при работе сетевой карты Frame latency (вы можете почитать об этом в моей предыдущей статье так же на примере разработки онлайн игр).
В настоящее время я продолжаю разрабатывать сервис добавляя новые механики в игру (полагаю в части архитектуры существенных изменений более не будет).
О новых фичах и о том что будет дальше вы можете узнать подписавшись на выпуск новых статей в моем профиле.
По результатам моих исследований на рынке нет коробочных версий для создания Авторитарных игровых серверов, так что полагаю продукт будет полезен многим. Если у вас есть опыт написания подобных сервисов будут рад услышать его в комментариях или по личным контактом со мной с сайта.
История:
- Введение
- Масштабируемость и асинхронность
- WebSocket
- Redis
- LUA и JavaScript
- Выбор технологий, протокола и архитектурный шаблон Entity Component System
- Игровые локации (тайловые карты)
- Клиентская часть на Unity
- Игровые серверные механики
- Открытый бесшовный мир в 2D игре
- FPS, Ping, паузы между командами, интерполяция и экстраполяция
- Очереди и параллельное программирование на CPU
- Event-driven паттерн, JSON-RPC и почему не сервисная (SOA) архитектура
- Сетевая карта и задержка кадра (Latency frame) по RFC 2544 (1242)
- Создание сервера для онлайн ММО игр на PHP
- Готовое MVP сервиса 2D MMO RPG игр (realtime)