Создание онлайн сервера для мобильных многопользовательских, realtime 2D игр (жанра RPG и стратегии) с API на PHP ч. 2

от автора

Для тех кто еще не успел ознакомится с первой частью рублике рекомендую прочитать первую статью где я рассказываю о самой идеи API сервиса. В этой части будут рассмотрены проблемы с которыми предстоит столкнуться

Асинхронность и масштабируемость

Когда наш сервер обрабатывает запрос игрока на то или иное действие — требуется время на вычисления (к моменту написания статьи это ~5-10 мс). Когда игроков тысячи — время пропорционально увеличивается и последний игрок в очереди ожидает завершения вычисления других игроков. Для того что бы этого не было — нужно обрабатывать запросы параллельно . Подробнее зачем это нужно можно найти в моем видео :

Варианты

PHP на сегодняшний день работают в двух режимах

  • FPM (тот режим когда есть один «управляющий» процесс и куча дочерних открываемых динамически по числу обращений например к сайту) — это процесс короткого жизненного цикла

  • CLI — режим работы переводится как Command Line Interface, но при слове командная строка многие считают что для его работы на экране она должна быть обязательно открыта — это не так , по сути php скрипт работает как как демон, в фоне. У него нет условного управляющего процесса. Это процесс долгого жизненного цикла

Оба эти режимы тратят +- 2 мс на поднятие процесса, в CLI режиме мы можем написать свой собственный сервер на обработку запросов (и не только http но и websocket, что и будет выбрано в качестве «роутера» держащего игроков) .

У каждого есть ряд особенностей с которыми предстоит столкнуться. Каждый из вариантов может быть вызван друг из друга (например CLI процесс можно вызвать из FPM функциями семейства exec что тратят +- 30 мс на вызов, а из CLI можно вызвать FPM отправив напрямую в сокет fpm’а запрос на поднятие процесса и даже эмулировать передачу POST и GET данных)

Мы можем использовать CLI для управления сервером (скрипт который слушает запросы пользователей) который создает новые FPM процессы (через сокет) в сервисы (предположим наша архитектура API будет построена в виде сервисов) не дожидаясь ответа (те отправил и забыл) что бы поддерживать асинхронность.

Так же NPC должны жить своей жизнью (ходить атаковать) и они будут жить в режиме CLI, о чем я снял подробное видео:

Проблемы

  • На поддержания минимального функционала процесса CLI так или иначе тратится 0.7% процессорного времени (рассматриваем сервер с одним ядром) и большое количество NPC «съесть» весь процессор

  • PHP выделяет оперативной памяти (и в CLI и в FPM) на процесс больше его фактического потребления ~+50% (этот параметр можно посмотреть функцией memory_get_usage(true) ) что при большом количестве NPC процессов «съест» оперативной памяти больше положенного. В добавок количество одновременных процессов PHP FPM ограничено настройками конфигурационного файла

  • При каждом запуске CLI в память загружаются общие для работы скрипты php (те сам фреймворк)

  • При использовании библиотек типа Apcu (позволяет кэшировать в памяти данные в тч ряд ресурсов, объекты и массивы php ) в режиме Cli мы не можем получить то что создано в режиме Apcu (и наоборот, тк в FPM этот кэш живет до перезагрузки php-fpm а в CLI до окончания работы демона и только в нем самом) и тем самым в CLI нужно искать другой способ доступа к общей памяти

  • Но и работать только в CLI (например когда приходит запрос от игрока и надо поднять процесс) мы не можем. Каждый из режимов тратит на поднятие процесса время (новый cli процесс создается из php функциями семейства exec что тратят +-30 мс), fpm +-2 мс , а хорошим пингом в играх считается 60 мс

Решения проблем

  • Для решения потребления памяти на каждый раз загружаемые скрипты в php служит технология opcache что по сути выделит в общую память весь фреймворк (те файлы php загружаются начале скрипта через autoload composer или прямым require). Демонстрация его работы в видео:

  • Количество одновременных php fpm можно увеличить изменения настроек самого fpm однако не решит проблему ниже

  • Объединения NPC и объектов в так называемые управляющие «пулы» которые управляют синхронно десятками-сотнями живыми npc и объектами (например 1 пул — 1 карта) Это решит проблему чрезмерного потребления памяти и процессора (потому что на поддержания ничего не делающего CLI сценария процессор тратит и так и так 0.7% и 100 сценариев CLI тратят больше пула в 100 NPC под его управлением в десятки раз). Пример того как бы это выглядело можно посмотреть в видео:

  • мы так же не можем использовать общий кеш Apcu (который кеширует ресурсы, объекты и массивы php без какой либо сериализации) для доступа к нему нашими NPC (тк они работают в CLI) , но мы можем посмотреть в сторону библиотек для работы с общей памятью например shmop и подобные в php

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

Для тех кого заинтересовала идея моего творчества имеется адрес проекта где я делюсь исходниками кода. Буду признателен за лайк

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Стала ли статья лучше по качеству / восприятие чем первая часть?
60% Все так же плохо и ничего не получится 6
10% Стало чуть лучше, но я не верю что выйдет задуманный сервис 1
30% Лучше или хуже, но сама идея такого сервиса кажется реальной и полезной 3
Проголосовали 10 пользователей. Воздержались 2 пользователя.

ссылка на оригинал статьи https://habr.com/ru/post/670050/