RE:NODE

Эксплуатация12 мин чтения

Краш-циклы игрового сервера: поиск плохого мода

Как читать цикл крашей игрового сервера, отличить сломанный мод от повреждённого сохранения или плохого конфига и методом деления найти виновный файл за несколько запусков.

0 прочтений

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

В этой статье подробно разобран метод диагностики со спецификой тех систем модов, которыми реально пользуются: плагины и модпаки Minecraft, BepInEx, Oxide и Carbon, SourceMod, ресурсы FiveM, списки модов на базе Workshop. Коды выхода и убийства из-за нехватки памяти - причины рестартов, не связанные с модами, - описаны в статье почему игровой сервер постоянно перезапускается, и здесь мы опираемся на неё, а не повторяем.

Сначала остановите цикл#

Цикл сам уничтожает свои улики. Каждый рестарт прокручивает консоль, ротирует лог, а в некоторых играх перезаписывает отчёт о краше более новым, который говорит меньше. Прежде всего:

  1. Остановите сервер кнопкой Stop в панели, а если он продолжает подниматься - нажмите Kill.
  2. Отключите всё, что его перезапускает: расписание, настройку рестарта при краше, плагин-watchdog, автоматический рестарт txAdmin в FiveM.
  3. Сделайте backup и заблокируйте его. Вы собираетесь перемещать файлы. Если дело касается сохранения, вам нужно состояние до ваших экспериментов.

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

На RE:NODE цикл крашей виден и снаружи. Наблюдатель каждые две минуты проверяет, не уменьшился ли uptime и не ушёл ли сервер в офлайн; три незапрошенных рестарта за час выводят предупреждение на страницу сервера и автоматически открывают тикет, а шесть приостанавливают сервер, пока кто-нибудь на него не посмотрит. Предупреждение должно дойти до вас, пока цикл ещё просто раздражает, а если вы сами остановите сервер, счётчик сбросится.

Классифицируйте краш по моменту падения#

Самое полезное наблюдение - момент, когда сервер умирает. Он сужает поиск ещё до того, как вы откроете хоть один файл.

Когда падаетНаиболее вероятные причиныЧто попробовать первым
До того, как игра что-либо выведетНе та версия runtime, плохая строка запуска, отсутствующий бинарникПрочитать первые десять строк вывода
Во время загрузки модов или плагиновМод, несовместимый с версией игры, или отсутствующая зависимостьПрочитать лог загрузчика модов, затем делить
Во время загрузки мираПовреждённое сохранение, мод, добавляющий контент в мир, конвертация версииЗапустить с новым именем мира
Через несколько минут после стартаКонкретная область, сущность или плановое событие; памятьСледить за графиком памяти и последними строками перед падением
Когда заходит определённый игрокПовреждённые данные игрока, предмет мода в инвентареУбрать данные этого игрока в сторону
В фиксированное времяРасписание, автоматическое событие, таймер плагинаПроверить расписания и плагины с таймерами

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

Читайте первую ошибку, а не последнюю#

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

code
[12:04:11 INFO]: Loading 47 plugins[12:04:12 ERROR]: Could not load 'plugins/ShopPlus-3.2.jar' in folder 'plugins'org.bukkit.plugin.UnknownDependencyException: Unknown/missing dependency plugins: [Vault][12:04:15 WARN]: Plugin EconomyBridge v1.4 generated an exception while enablingjava.lang.NullPointerException: Cannot invoke "Economy.getBalance" because ......[12:04:31 ERROR]: Encountered an unexpected exception

Последняя строка - это краш. Первая ошибка его объясняет: не хватает зависимости, поэтому второй плагин получил null там, где ожидал экономику, поэтому что-то ниже упало. Исправьте первую - и остальные обычно исчезают. Общая техника чтения stack trace снизу вверх и строки, которые только выглядят фатальными, - в статье как читать консоль сервера.

Где искать первую ошибку, зависит от игры, и пути собраны в статье логи игрового сервера простыми словами. Самые важные для циклов крашей:

  • Minecraft: logs/latest.log и самый новый файл в crash-reports/, плюс hs_err_pid*.log в корне сервера, если упала сама JVM.
  • Игры с BepInEx (Valheim и другие): BepInEx/LogOutput.log, где перечислен каждый плагин по мере загрузки.
  • Rust с Oxide: oxide/logs/; с Carbon - carbon/logs/.
  • Игры на Source с SourceMod: addons/sourcemod/logs/errors_<date>.log.
  • FiveM: консоль сервера и логи txAdmin; ошибки ресурсов выводятся с именем ресурса в квадратных скобках.
  • Серверы на Unreal Engine (Palworld, Satisfactory, Abiotic Factor, The Isle): <Project>/Saved/Logs/<Project>.log и Saved/Crashes/.

Исключите скучные причины за пять минут#

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

  • Память. Посмотрите на график памяти в минуту перед каждым падением. Линия, которая поднимается до лимита тарифа и затем вертикально падает, - это остановка из-за нехватки памяти, а не краш. На RE:NODE контейнер при достижении лимита останавливается и перезапускается начисто, а не уходит в swap. Решение - больше памяти, меньше модов или меньшая дальность прорисовки, а не деление модов.
  • Диск. На заполненном диске сохранения не проходят, а неудачное сохранение может оставить файл мира размером ноль байт, на котором упадёт следующий запуск. Проверьте свободное место в файловом менеджере или командой df -h.
  • Порты. Address already in use, Failed to bind или BindException означают, что порт занят - часто предыдущим экземпляром, который не до конца завершился, или потому, что после копирования два сервера делят один порт.
  • Учётные данные. Отозванный или использованный другим сервером токен игрового сервера Steam, истёкший ключ Cfx.re, перевыпущенный токен Klei. Обычно они выводят понятное сообщение и завершают работу, а политика рестартов повторяет это бесконечно.
  • Версия. Обновление игры накануне ночью при модах, собранных под предыдущую версию. Лог загрузчика модов обычно прямо называет несовпадение версий.

Если ничего из этого не объясняет проблему, сбой в файлах: модах, конфигурации или мире.

Отделите мир от модов#

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

  • Свежий мир запускается и работает. Проблема в сохранении - повреждённый чанк, сломанная сущность, инвентарь игрока с предметом удалённого мода. Моды, скорее всего, в порядке.
  • Свежий мир падает так же. Проблема в установке - моды, плагины, конфигурация или файлы игры. Мир, скорее всего, в порядке.

Потом верните имя обратно. Свежий мир - это диагностика, а не замена, и оригинал лежит рядом нетронутым. Для игр, где всё привязано к имени сервера, а не мира (Project Zomboid, Don't Starve Together), вместо этого скопируйте сервер под тестовым именем.

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

Деление модов пополам в поисках виновного#

Когда тест со свежим миром указывает на установку, а первая ошибка не называет виновника, делите пополам. Метод одинаков в любой игре:

  1. Создайте вне каталога модов папку с названием вроде disabled.
  2. Переместите в неё половину модов. Держите зависимости вместе с модами, которым они нужны: библиотека, отделённая от зависящих от неё модов, даёт другую ошибку и путает результат.
  3. Запустите сервер. Если он падает так же, сбой в оставшейся половине. Если запускается - в той, которую вы убрали.
  4. Продолжайте делить подозрительную группу, пока не останется один мод.
  5. Верните всё остальное и убедитесь, что сервер запускается, если убран только этот мод.

Число запусков - это двоичный логарифм числа модов, округлённый вверх: 16 модов - 4 запуска, 64 - 6, 256 - 8. Записывайте каждый раунд - какие моды были установлены и что произошло, - потому что к пятому раунду никто уже ничего не помнит.

Часто встречаются два осложнения. Сбой может давать пара конфликтующих модов, и тогда обе половины по отдельности запускаются нормально; в этом случае оставьте одну половину полностью установленной и делите другую на её фоне. А некоторые сбои зависят от мира: мод падает, только когда загружается определённый блок или существо. Если свежий мир запустился нормально, делите на реальном мире (на копии), а не на свежем.

Где лежат моды в разных системах

Система модовПапка для деленияКак отключить один мод
Плагины Paper/Spigotplugins/Убрать .jar; папку данных оставить
Forge, NeoForge, Fabricmods/Убрать .jar; проверить зависимые моды
BepInEx (Valheim и другие)BepInEx/plugins/Убрать .dll или его папку
Oxide / uMod (Rust)oxide/plugins/Убрать .cs; Oxide выгрузит его на лету
Carbon (Rust)carbon/plugins/Убрать .cs
SourceModaddons/sourcemod/plugins/Переместить .smx в plugins/disabled/
FiveMстроки ensure в server.cfgЗакомментировать строку через #
Project ZomboidMods= и WorkshopItems= в .ini сервераУдалить ID из обеих строк
DayZ, Arma 3параметр запуска -mod=Убрать @Mod из списка

SourceMod считает plugins/disabled/ местом, откуда ничего не загружается, поэтому с ним работать аккуратнее всего. Oxide и Carbon перезагружают плагины без рестарта, так что плагин, роняющий весь сервер при загрузке, там редкость; цикл крашей на сервере Rust с фреймворками чаще означает, что сам фреймворк устарел после обновления игры. В FiveM удаление ресурса, от которого зависят другие, - ядра фреймворка, инвентаря, oxmysql - тянет за собой большую часть сервера, поэтому делите дополнительные ресурсы, а ядро оставьте на месте.

Деление перемещением файлов безопаснее всего делать в файловом менеджере или по SFTP при остановленном сервере. Как перемещать целые папки без повторной загрузки, описано в статье SFTP и файловый менеджер.

Конфигурация, которая роняет сервер#

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

  • JSON (инструменты вокруг Palworld, конфиги модов Valheim, многие игры на Unity): одна лишняя запятая в конце или пропущенная кавычка - и парсер сдаётся. Вставьте файл в любой JSON-валидатор.
  • YAML (конфиги плагинов Minecraft, paper-global.yml): табуляция вместо пробелов или отступ, сбитый на один, ломают файл. Paper и большинство плагинов выводят номер строки.
  • INI (игры на Unreal): значение в одной очень длинной строке, как в PalWorldSettings.ini, легко сломать, удалив скобку или запятую.
  • XML (7 Days to Die, файлы экономики DayZ): незакрытый тег. DayZ особенно беспощадна к types.xml, и ошибка там может остановить сервер или тихо опустошить экономику лута.
  • Lua (SandboxVars.lua в Project Zomboid, настройки модов Don't Starve Together): пропущенная запятая между записями.

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

Когда сломаны сами файлы игры#

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

Для игр Steam обновление через SteamCMD с validate хеширует каждый файл и заменяет всё, что не совпадает с опубликованной версией. В панелях на базе Pterodactyl похожую работу делает переустановка из панели, но прежде чем её нажимать, прочитайте, что переустановка у вашего хостера делает с файлами, - некоторые удаляют больше, чем бинарники игры. В любом случае сначала сделайте backup. Почему validate - инструмент ремонта, а не то, что нужно запускать при каждом старте, объяснено в статье автоматизация обновлений игрового сервера.

Как предотвратить следующий#

Цикл крашей дёшево диагностировать, если заранее подготовлены три вещи:

  • Журнал изменений. Одна строка на изменение: дата, что добавлено или обновлено, кем. По десять секунд на запись, и «ничего не менялось» превращается в «во вторник Workshop обновил два мода».
  • Backup перед каждым изменением, заблокированный, чтобы ротация его не удалила.
  • Тестовый сервер для обновлений модов и патчей игры. Дешёвая схема описана в статье тестовый сервер рядом с основным, а привычки, которые делают список модов поддерживаемым, - в статье как держать модовый сервер в чистоте.

И по возможности обновляйте моды по одному. Десять обновлений разом и краш после них - это деление пополам; одно обновление и краш после него - это готовый ответ.

FAQ#

Как найти мод, из-за которого падает сервер?

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

Почему сервер каждый раз падает в разном месте?

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

Может ли повреждённый мир вызвать цикл крашей?

Да, и его легко спутать с проблемой мода. Запустите сервер один раз с новым именем мира: если свежий мир работает, проблема в сохранении. Восстановите последний загружающийся backup или удалите повреждённый файл региона или игрока.

Стоит ли переустанавливать сервер, чтобы исправить цикл крашей?

Только после всего остального и только после backup. Переустановка уничтожает улики и редко затрагивает причину, которая обычно в модах, конфигах или мире - а их вы тут же вернёте обратно.

Приостановит ли хостер сервер, который постоянно падает?

На RE:NODE три незапрошенных рестарта за час вызывают предупреждение и открывают тикет, а шесть приостанавливают сервер. Если вы сами остановите сервер на время разбирательства, цикл прекратится, а счётчик сбросится.


Комментарии

Полностью анонимно: без аккаунта, без почты, без cookie. Мы храним имя, которое вы ввели, текст и время - больше ничего. Количество ссылок ограничено, разметка не отображается.

0/2000