Создание сервера для онлайн ММО игр на PHP ч. 13 — Event-driven паттерн,JSON-RPC и почему не сервисная (SOA) архитектура

В процессе разработки разработчик часто реализовывает функционал, который кажется ему логичным даже не задумываясь как этот архитектурный стиль называется. При этом читая про паттерны и шаблоны проектирования архитектуры в научной литературе информация может показаться сложной, а названия трудно запоминающиеся.

В этой статье я без привязки к коду объясню простым языком и в картинках как можно применять в разработке архитектуры авторитарного сервера для онлайн игр шаблон проектирования Event-driven.

Event-driven - Событийно-ориентированная архитектура

Создание сервера для онлайн ММО игр на PHP ч. 13 — Event-driven паттерн,JSON-RPC и почему не сервисная (SOA) архитектура

А теперь окунемся в теорию этого шаблона на Википедии в русском и английском варианте убедиться что все сделано правильно:

1. Генераторы событий (агент, продюсер) - они у нас есть и это игровые события (команды, которые могут отправлять игроки и генерировать NPC - например движение и атака на языках программирования LUA, JavaScript и PHP). На данный момент пренебрегая размером пакета я использую пакеты с командами стиля JSON-RPC.

Создание сервера для онлайн ММО игр на PHP ч. 13 — Event-driven паттерн,JSON-RPC и почему не сервисная (SOA) архитектура

2. Механизм обработки событий (подписчик) - Это не обязательно должен быть сервис (приложение которое может быть расположено в т.ч. на другой физической машине).

Можно использовать и корутину (как например есть в Unity или файберы в PHP) как работающий асинхронно в текущем процессе обработчик событий, и отдельный процесс работающий на той же машине и отдельный поток (thread)

В любом случае подразумевается что это процесс работает в бесконечном цикле (в языке PHP можно комбинировать это с тиками и сигналами) или ставится на паузу и ждет поступления команд.

Такой подход можно реализовать используя сокеты (в т.ч. на базе TCP) или прерывания (в PHP это можно реализовать через библиотеку Event что пришла на замену устаревшей Libevent, EV и наконец Swoole которой я отдаю предпочтения за счет того что у нее есть свои библиотеки для создания сервера, корутины для асинхронного выполнения запросов в БД и записи в фаилы и channel как те о которых я писал в статье про обмен данными между потоками, но для обмена данных между корутинами).

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

первым делом - обработчик событий
первым делом - обработчик событий
может, но не обязательно сделать его как сервис
может, но не обязательно сделать его как сервис
Создание сервера для онлайн ММО игр на PHP ч. 13 — Event-driven паттерн,JSON-RPC и почему не сервисная (SOA) архитектура

3. Канал событий (брокер) - в Википедии явно не указано наличие брокера сообщений и его отсутствие не означает что архитектуру нельзя будет назвать Event-driven, однако в высоко нагруженных системах без брокера ваше приложение будет работать медленно если Механизм обработки событий будет и принимать данные от Генератора событий и эти события выполнять в одном потоке.

Каналы событий можно использовать разные (если вы читали мои статьи я часто называю это шиной данных), необходима гарантированная доставка данных (UDP не рассматриваем), а так же понимание нужна ли нам масштабируемость. Вот пару вариантов шины обмена данных

  • Сокеты (PHP предоставляет для этого довольно обширный функционал)
  • Протокол TCP (в т.ч. и его WebSocket протокол который можно создать в PHP на базе функций по работе с сокетами)
  • Shared Memory (PHP предоставляет лишь базовые инструменты в библиотеке Shmop и отдельными функциями при работе с Семафорами)
  • HTTP
  • Каналы (channel) обмена данными между сопроцессами (корутинами) или потоками (процессами) о которых было написано выше .

В нашем случае брокером выступает Websocket сервер

4. Последующее действие, управляемое событиями - как опять же нам сообщает русскоязычная версия Википедии этот пункт не является обязательным (как например не на все события игровой сервер обязан что-то возвращать - например когда стало нельзя пройти в координаты из команды игрока).

После пакетной обработки игровым сервером текущих событий цикла (я его называю кадром сервера) он возвращает все изменения агентам (игрокам).

Сервисная архитектура (SOA)

В проекте о котором ведется серия статей не основан на сервисной архитектуре. Отвечая на порос "Почему?":

Если обратится к Википедии одним из главных принципов сервисной архитектуры является независимость от того на каком языке написан сервисы - они могут вызваться через какой-то общепринятый канал взаимодействия (например HTTP запросы в микро сервисной архитектуре через REST API методы). Этот подход хорошо зарекомендовал себя в WEB разработке, но для ММО игрового сервера может быть в ряде случаем медленным, сложным в реализации и поддержке, но не всегда.

В частности приложения для создания игровых карт может работать как сервис, написано на любом языке программирования, находится на отдельной физической машине - обращение к приложению из вне для получения сетки карты и ее графики происходит по HTTP в момент авторизации игрока на сервисе авторизации - который так же может "жить" отдельно.

Можно видеть и в данных случаях - это WEB приложения и HTTP обмен. Что же касается главных приложений: WebSocket и Игрового сервера (выполняющий расчеты разных механик и команд игроков) - то они тесно связаны языком программирования который обеспечивает им быстрый обмен данных между собой на скорости 1 600 000 запросов в одну сторону, хотя кроме обмена данными другой жёсткой связи нет (т.к. они работают параллельно в разных протоках как разные процессы со своим кодом и набором библиотек).

Создание сервера для онлайн ММО игр на PHP ч. 13 — Event-driven паттерн,JSON-RPC и почему не сервисная (SOA) архитектура

Однако возможно сделать их и в виде независимых сервисов (и писать каждый, в том числе на разных языках программирования), но для этого понадобиться реализовать обмен между этими сервисами, где самым быстрым протоколом будет обмен данными через общую память (Shared Memory), но эти два сервиса будут должны находится на одной физической машине для использования такого обмена.

Согласно официальному описанию ее эталонной архитектуры допускается что системы на основе сервисов (SOA) могут не быть масштабированы (хотя стремление к этому является целью). Многие разработчики считают иначе (что сервисы обязательно должны быть автономны и способны к масштабированию) выдавая цели SOA за обязательное требование к ним.

Если допускаются сервисы на основе модели SOA которые можно масштабировать - есть и те сервисы на основе SOA которые нельзя масштабировать
Если допускаются сервисы на основе модели SOA которые можно масштабировать - есть и те сервисы на основе SOA которые нельзя масштабировать

Подписывайтесь на мой профиль если вы хотите узнать о выходе новых статей, так же я публикую видео о процессе разработки данного стартапа на Youtube.

Буду благодарен за лайк к статье.

История:

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

Привет, коллега! Очень интересно читать как ты делаешь ММО, у нас очень разные подходы, поэтому ещё и познавательно) спасибо

Мы с вами обсуждали в комментариях на вашем Youtube канале что пропускная способность != количеству пакетов (команд) которые сервер способен считать с сетевой карты и почему важен CPU . Я написал статью на эту тему более подробно (если вам будет интересно)
https://dtf.ru/gamedev/1899928-sozdanie-servera-dlya-rossiyskih-onlayn-mmo-igr-ch-14-setevaya-karta-i-zaderzhka-kadra-latency-frame-po-rfc-2544-1242

1

Спасибо Я уже успел посмотреть и ваши ролики на канале

Комментарий недоступен

если и рассматривать node js то из за его socket io из коробки (который можно реализовать). В остальном же там где асинхронность нужна была - это не такие уже и критические моменты, т.к. с критическими нужно работать параллельно на CPU или GPU (видеокарте)

Каждая локация может быть отдельной тачкой. И на каждой локации всегда есть 2 процесса - websocket сервер (что соединение с игроками обрабатывает) и игровой (в котором эти команды обрабатываются каждый кадр) и вот в них нужен обмен в памяти

Да, микросевисы - о чем выше этого абзаца и пишу что сейчас такой архитектуры нет, но ее возможно сделать