Создание сервера для онлайн ММО игр на PHP ч.14 — Сетевая карта и задержка кадра (Latency frame) по RFC 2544 (1242)

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

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

В конце статьи будет приложена видео версия.

сетевая карта

сетевая карта

Пропускная способность

Когда речь идет про сетевые карты, роутеры и другие устройства для приема и передачи пакетов главным их показателем считается пропускная способность которая часто составляет 100 Мегабит в секунду на домашних устройствах.

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

Уменьшение размера пакета в первую очередь ?!

Например, многие полагают что при фактической скорости 10 Мб/с интернета и размере пакетов от клиентов 64 байта смогут обработать 1 250 000 таких пакетов в секунду (1 Мбит = 125 000 байт) и в первую очередь стремятся уменьшить размер пакета следующим образом:

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

  • Используют на этапе проектирования нечитабельные (кроме самого их автора) байт — флаги в которых кроется какая-то команда (взамен использования текстовых понятных человеку команд, например в том же json)

  • Использование сжатие (которое тратит время перед отправкой пакетов и тормозит процесс)

Почему CPU важен при работе с сетью

ea33c65f62c1e216b6fb9aeda0e87b10.png

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

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

И вот тут и кроется самое основное, что должен предусмотреть разработчик — возможность работы сервера в нескольких параллельных процессах (потоках), а как я рассказал в другой статье за это отвечает количество количество ядер процессора CPU и их thread (нитей).

Если сервер работающих в один поток не способен прочитать и 10% принятых пакетов (бывает что и 1%), то уменьшения размера пакетов (которые в играх обычно небольшие) даст в лучшем случае прирост в скорости сколько же — выглядит не первоочередной задачей, а скорее той, которую нужно решать в самую последнюю очередь для оптимизации и уменьшения количества ядер CPU.

Задержка сетевого устройства

Для определения скорость с которой сетевое устройство может передать пакет дальше производители этих устройств публикуют в тестах выполняемых стандартом под названием RFC 2544 в разделе Latency (Frame Latency). Иногда можно встретить упоминание RFC 1242 на котором основаны методы замера.

Ниже представлена выдержка из инструкции тест-анализатора сетевого оборудования, что означает показатель Latency (задержки)

фото из инструкции Беркут-ET http://metrotek.center/files/doc/all/b3et-ug_1.2.2_ru.pdf

фото из инструкции Беркут-ET http://metrotek.center/files/doc/all/b3et-ug_1.2.2_ru.pdf

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

Приведу примеры таких тестов, где us — микросекунды:

https://www.albedotelecom.com/src/lib/WP-RFC2544.pdf

https://www.albedotelecom.com/src/lib/WP-RFC2544.pdf

7b1c84953bc13fcbb451781b35610112.pnghttps://miercom.com/pdf/reports/20121129.pdf

https://miercom.com/pdf/reports/20121129.pdf

А вот пример теста где уже подсчитано количество пакетов (Frames) в секунду:

236f44fc58411d883d3549a3936ea568.png

Согласно публичным тестам задержка (Latency) для пакетов 64 байта в среднем находится от 7 до 50 микросекунд, т.е. от 135 000 до 20 000 уже полученных устройством пакетов в секунду можно с него считать в рамках одного потока.

Это позволяет сделать вывод, что задержка достаточно серьёзная (если само устройство при скорости 10 Мбит/c способно принять 1 250 000 аналогичных пакетов).

Выводы

Одним из самых первых и важных решений при разработке сервера — это обеспечить его работы в многопоточном режиме, т.е. что бы ваш сервис представлял собой несколько потоков (они могут делить между собой память как в языке C#, использовать каналы Channel как я языке Go или PHP или даже быть разными процессами обмен данных между которых можно наладить например установив TCP соединение между, использовать сокет (фаил) для обмена информации и т.д.).

Этот подход можно заметить и в WEB серверах (apache, nginx) и менеджерах процессов PHP — FPM где нужно вручную указать количество этих параллельных потоков (процессов) — они называются в них workers. Имейте в виду, что помимо обработки пакетов сервером для работы ОС нужно оставлять свободными (в зависимости от того что на ней еще работает, например база данных).

60adbca87f1b4bd7419f8cd80fd51f7e.png

Помимо того что бы сервер работал в многопоточном режиме на физической «машине» (железе) должно быть достаточное количество нитей (thread) у ядер CPU что бы ваши потоки (процессы) находились на разных нитях и действительно работали параллельно (в ОС есть встроенный балансировщик на который как я полагаю можно положиться как минимум на первых порах разработки).

В заключение

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

Подписывайтесь на мой профиль если вам интересно данное направление — я веду разработку собственного авторитарного сервера и демонстрационной онлайн игры. Все статьи пишутся мной лично на основе собственного опыта и исследований. Так же я веду видео блог на Youtube

В следующей статье я расскажу как ускорить ваш TCP сервер в 2 раза отключив лишь один стандартный параметр.

Видео версия данной статьи:

© Habrahabr.ru