MAATRIX GAMES / Блог / Оптимизация сервера под высокую нагрузку

Оптимизация сервера под высокую нагрузку

MAATRIX GAMES

Стрим набрал охват, комьюнити выросло с 15 до 150 человек за неделю, или вы просто готовитесь к открытию сезона с большим онлайном — и вдруг сервер, который спокойно работал месяцами, начинает икать под нагрузкой: тики проседают, RCON отвечает через раз, игроков телепортирует. Это решаемо, но чинить это нужно было вчера, а не когда ETA до жалоб в Discord — пять минут. Разберём, что реально можно выжать из сервера до того, как единственным ответом останется апгрейд тарифа.

Лимиты ОС: файловые дескрипторы и сетевые буферы

Первое, во что упирается сервер под нагрузкой — совсем не CPU, а лимиты самой ОС. Каждое сетевое соединение, каждый открытый лог-файл, каждый чанк на диске в некоторых движках — это файловый дескриптор, и у Linux по умолчанию их прискорбно мало.

Проверить текущий лимит для процесса:

ulimit -n

Дефолт в 1024 на сервер с полусотней игроков и активным плагинным логированием вылетает влёт. Поднять лимит для пользователя, от которого запускается сервер (обычно steam или отдельный сервисный юзер), правится в /etc/security/limits.conf:

steam soft nofile 65535
steam hard nofile 65535

Если сервер запускается через systemd-юнит — лимит из limits.conf может не наследоваться, нужно прописать его прямо в юните:

[Service]
LimitNOFILE=65535

После правки — systemctl daemon-reload и рестарт сервиса, иначе изменения не подхватятся.

Второе узкое место — сетевые буферы ядра. Дефолтные значения net.core.rmem_max и net.core.wmem_max в большинстве дистрибутивов рассчитаны на обычный веб-трафик, а не на десятки UDP-пакетов в секунду от каждого из полутысячи клиентов (привет, Rust и любой Source-движок). Добавьте в /etc/sysctl.conf:

net.core.rmem_max = 26214400
net.core.wmem_max = 26214400
net.core.netdev_max_backlog = 4096
net.ipv4.tcp_fin_timeout = 15
net.core.somaxconn = 1024

Применить без перезагрузки: sysctl -p. Это не магия, которая сама по себе поднимет TPS, но без этого шага сервер будет ронять пакеты на ровном месте ещё до того, как игра успеет что-то оптимизировать на своей стороне.

Тариф под ожидаемое число игроков — считаем заранее, а не по факту

Самая частая ошибка — оптимизировать сервер, который изначально не тянет заявленную нагрузку по железу. Тюнинг конфигов даёт проценты, а не разы: если под пиковый онлайн не хватает RAM или ядер, никакой ulimit это не исправит.

Прикидка памяти — не точная наука, версии и моды сильно её сдвигают, но ориентир для планирования такой:

Игра / движокИгроковОриентир RAM
Minecraft (Paper, vanilla-подобный мир)20–304–6 ГБ
Minecraft (Paper + модпак/датапаки)20–308–10 ГБ
Rust (ванильная карта)1008–10 ГБ
Rust (карта 4500+, много плагинов Oxide)150–20016 ГБ
CS2 (несколько инстансов на одном хосте)10 на инстанс2–3 ГБ на инстанс
ARK: Survival Ascended20–3012–16 ГБ

Это именно ориентир для прикидки бюджета, а не гарантированные цифры — конкретное потребление зависит от плагинов, версии сборки и настроек мира, проверяйте на своём конфиге через мониторинг (о нём ниже). Если знаете, что сезон/ивент/анонс приведёт к всплеску онлайна — берите тариф с запасом заранее. Даунгрейднуть обратно после пика — не проблема, а вот поднимать тариф в момент, когда сервер уже лежит под нагрузкой и половина игроков клеймит лаги в отзывах — то ещё удовольствие: миграция или ресайз посреди активного онлайна почти всегда означает даунтайм, а первое впечатление у новых игроков вы уже потеряли.

Отдельно — ядра. Большинство игровых серверов (в первую очередь на Source-движке и модах на нём) однопоточные для тикового цикла: игре плевать, что у вас 16 ядер, если её основной луп утилизирует одно. Здесь важнее частота ядра, чем их число. При выборе тарифа смотрите не только на "vCPU: 8", а уточняйте у хостера частоту и то, не делит ли он физическое ядро между несколькими клиентами (oversell) — на высокой нагрузке это ощущается быстрее всего.

Нужен игровой сервер?

MAATRIX GAMES — 45+ игр, деплой за минуты, DDoS-защита, автобэкапы. Тарифы от 399 ₽/мес.

Создать сервер

Кэширование и баланс частоты дисковых операций

Автосохранения — классический компромисс. Слишком редко — рискуете миром/прогрессом при краше. Слишком часто — каждое сохранение это I/O-стопор, который на under-provisioned диске (особенно на дешёвом shared-hosting без NVMe) подвешивает тикрейт на секунду-другую именно в момент сохранения, и на пике онлайна это будет заметно каждому игроку одновременно.

Для Minecraft (Paper/Spigot) частота автосохранения регулируется через spigot.yml:

world-settings:
  default:
    save-user-cache-on-stop-only: true
    merge-radius:
      exp: 3.0
      item: 2.5

Плюс сам таймер автосохранения save-interval в bukkit.yml — по умолчанию каждые 6000 тиков (5 минут). Для сервера под высокой нагрузкой разумно развести автосейв игроков и мира по разным моментам, чтобы не ловить двойной I/O-удар, и не увеличивать интервал бездумно — 10+ минут между сохранениями на активном PvP-сервере при краше это реально потерянный прогресс десятков людей.

Для Rust сохранение крутится через server.saveinterval (в секундах) в конфиге запуска. На большой карте с несколькими сотнями онлайна сохранение занимает заметное время само по себе — здесь баланс скорее в сторону "не слишком часто", раз сама операция тяжёлая:

server.saveinterval 600

Общий принцип для любого движка: если диск на тарифе — не NVMe, а обычный SSD (тем более HDD-remnants у бюджетных хостеров), запись мира/базы данных под нагрузкой становится узким местом раньше CPU. Проверить реальную загрузку диска в моменте: iostat -x 2 (пакет sysstat), смотрите на %util — если он упирается в 90-100% именно в момент автосейва, это прямой сигнал либо развести частоту сохранений, либо это уже повод для апгрейда тарифа на более быстрый диск, а не тюнинга конфига.

Сетевая оптимизация и задержка

Часть "лагов", которые игроки принимают за проблемы TPS — на самом деле сетевая задержка, а не тормозящий тик. Здесь оптимизация конфигов не поможет вообще — решает физическое расстояние сервера от аудитории. Если у вас RU-комьюнити, а сервер стоит в US — миллисекунды пинга съедают ту же самую "плавность", что и просевший TPS, просто источник проблемы другой.

Что реально в ваших руках на уровне ОС/сети:

  • держите MTU в норме (ip link show, дефолт 1500 обычно ок, но VPN/туннели между вами и хостером могут его резать — фрагментация пакетов добавляет задержку);
  • для UDP-тяжёлых игр (Rust, ARK, любой Source) убедитесь, что провайдер хостинга не режет UDP-трафик агрессивным QoS — это частая скрытая причина рывков именно под нагрузкой, когда обычный трафик QoS ещё пропускает, а под пиком начинает троттлить;
  • если сервер стоит за NAT/проброс портов — на высоком онлайне лишний хоп через NAT-таблицу хоста добавляет накладные расходы, которых нет при прямом внешнем IP.

Главный рычаг тут — правильный выбор локации сервера под аудиторию ещё на старте, до того как нагрузка выявит проблему постфактум.

Мониторинг заранее, а не по жалобам в чате

Оптимизация без метрик — это гадание. Если вы узнаёте о проблеме из сообщений "сервер лагает", вы уже опоздали минимум на полчаса — ровно столько игроки терпят, прежде чем написать. Настроенный мониторинг TPS, памяти, сетевых пакетов и диска показывает деградацию на графике за минуты до того, как её почувствуют игроки.

Минимальный набор, который стоит снять с сервера:

  • TPS/MSPT самой игры (для Minecraft — плагины вроде Spark, команда /tps, /mspt);
  • потребление RAM процессом (top, htop, или systemd systemctl status с cgroup-метриками);
  • сетевые дропы пакетов (netstat -su — колонка packet receive errors);
  • загрузка диска в моменты автосохранений, о чём писали выше.

Подробный разбор диагностики и конкретных инструментов — в статье про мониторинг TPS и лагов на игровом сервере. Настроить алерты на пороговые значения (TPS ниже 18, RAM выше 90%) до пика сезона — дешевле по нервам, чем разбираться в 2 часа ночи, почему сервер лежит.

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

Оптимизация на уровне самой игры

После лимитов ОС, диска и сети остаётся оптимизация внутри самого игрового процесса — она даёт заметный, но не безграничный запас прочности.

Для Minecraft (Paper) — снижение view-distance и simulation-distance в server.properties даёт едва ли не больше эффекта, чем всё остальное вместе взятое, потому что напрямую режет число активных чанков за тик:

view-distance=8
simulation-distance=6

В paper-world-defaults.yml полезны entity-activation-range и entity-tracking-range-distance — они ограничивают, сколько мобов/сущностей реально симулируется вокруг игроков, а не просто существует в мире. Подробнее про это и про модную/плагинную нагрузку — в статье про оптимизацию модов и TPS на Minecraft-сервере.

Для Rust — количество и качество плагинов Oxide/uMod напрямую бьёт по тикрейту при высоком онлайне: каждый хук плагина исполняется на каждом тике для каждого игрока. Отключите неиспользуемые плагины и проверьте нагрузку через oxide.plugins — иногда забытый тестовый плагин с кривым хуком съедает больше, чем сотня лишних игроков.

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

Нужен игровой сервер?

MAATRIX GAMES — 45+ игр, деплой за минуты, DDoS-защита, автобэкапы. Тарифы от 399 ₽/мес.

Создать сервер

Частые вопросы

С чего начать оптимизацию, если сервер уже лагает прямо сейчас?

Сначала смотрите на мониторинг — упирается ли сервер в CPU, RAM, диск или сеть. Тюнинг наугад без метрик почти всегда тратит время впустую, потому что причина у разных серверов разная.

Поможет ли SSD/NVMe вместо HDD, если проблема в тикрейте?

Напрямую нет — диск влияет на I/O-операции вроде автосохранений и чанк-стриминга, а не на сам расчёт тиков. Но если просадки совпадают по времени с автосейвом — да, поможет заметно.

Сколько вообще можно выжать оптимизацией без апгрейда тарифа?

По опыту — до 20-40% запаса на типовых конфигурациях, если сервер изначально не был совсем впритык по ресурсам. Если тариф изначально взят "впритык" под текущий онлайн, оптимизация даст немного воздуха, но не удвоит потолок.

Нужно ли что-то менять на уровне самой игры, если проблема только в сети (пинг)?

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

Как понять, что дело именно в тарифе, а не в конфиге?

Если после лимитов ОС, оптимизации автосохранений и настроек игры CPU/RAM всё равно упираются в потолок на пиковом онлайне — это физический предел выделенных ресурсов, дальше только апгрейд.