Создание сервера для Российских онлайн ММО игр на PHP ч. 2 — Масштабируемость и асинхронность

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

Статья устарела - читайте актуальную статью про масштабирование и открытый мир

Создание сервера для Российских онлайн ММО игр на PHP ч. 2 — Масштабируемость и асинхронность

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

Когда наш сервер обрабатывает запрос игрока на то или иное действие - требуется время на вычисления (к моменту написания статьи это ~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 мы не можем получить то что создано в режиме FPM (и наоборот, тк в 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

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

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

Подписывайтесь на мой профиль что бы не пропустить новые статьи

История:

55
14 комментариев

Дай бог всем столько свободного времни на бессмыслицы

2

Сказал человек, который все свободное время проводит на дтф

2

почему вы считаете что это бессмыслица?