RE:NODE

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

Почему игровой сервер постоянно перезапускается и как это исправить

Убийство из-за нехватки памяти, циклы падений, забытые расписания и истёкшие токены: как отличить их по кодам выхода и строкам консоли и что чинить.

Обновлено

1 прочтений

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

Сужаем круг за одну минуту#

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

Что вы видитеПочти наверняка
Консоль обрывается на полуслове, без ошибки, память вертикально росла перед этимЛимит памяти контейнера
Трассировка стека или названное исключение прямо перед концомПадение в моде, плагине или конфигурации
Происходит в одну и ту же минуту часа, стабильноРасписание или watchdog
Перед концом строки о плановом завершенииЧто-то попросило его остановиться
Он вообще не доходит до строки готовностиКонфигурация, порт, версия или учётные данные
Работает 30-60 секунд каждый раз, потом умираетПроверка аутентификации или тайм-аут watchdog
Умирает через предсказуемый аптайм независимо от игроковУтечка
Умирает только при пиковом числе игроковНастоящая нехватка

Последние две строки - самое полезное различие во всей статье. Утечка убивает сервер по часам: каждые шесть часов, каждые девять, независимо от того, онлайн двое или двадцать. Нехватка убивает его, когда мир загружен больше всего. Обе выглядят как «нехватка памяти», а лечатся по-разному.

Коды выхода: что на самом деле завершило процесс#

У каждого перезапуска есть число, и число это однозначно.

Код выходаСигналЧто это значит
0-Чистый выход. Процесс попросили остановиться, и он остановился
1-Приложение само завершилось с ошибкой
134SIGABRTСреда выполнения намеренно прервалась: фатальная ошибка JVM или V8
137SIGKILLУбит снаружи. В контейнере почти всегда это лимит памяти
139SIGSEGVОшибка сегментации. Нативное падение, обычно из-за мода или драйвера
143SIGTERMЗапрошена чистая остановка: кнопка Stop или Restart, либо деплой
255-Общая ошибка, часто из скрипта-обёртки, а не из игры
нет лога, график вертикалентрассировка или дампсначала строки завершениясначала названная ошибкаОн перезапустилсясмотрите код выходаКод 137убит снаружиКод 134 или 139среда сдаласьКод 0 или 143просили остановитьсяКод 1упал с ошибкой
Что завершило процесс

Одна оговорка про 137: такой код вы получите и от кнопки Kill, и от ручного kill -9. Если никто ничего не нажимал, это лимит памяти. Проверьте собственную запись ядра, если у вас есть доступ к шеллу:

bash
$ dmesg -T | grep -i "killed process"$ cat /sys/fs/cgroup/memory.eventslow 0high 0max 4812oom 19oom_kill 19

oom_kill больше нуля - это факт, а не теория. Девятнадцать убийств - это девятнадцать перезапусков, о которых вы не просили.

Нехватка памяти, самая частая причина#

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

Есть два отдельных потолка памяти, и они дают разные улики:

  • Собственный лимит среды выполнения. JVM, превысившая -Xmx, выбрасывает java.lang.OutOfMemoryError: Java heap space, это пишется в лог, часто многократно, и сервер нередко ещё какое-то время ковыляет в сломанном состоянии. Процесс Node аварийно завершается с FATAL ERROR: ... JavaScript heap out of memory и кодом выхода 134. Оба что-то печатают.
  • Лимит контейнера. Ничего не печатается, потому что не остаётся такой возможности. Код выхода 137, вертикальный график памяти и тишина.

Самая частая самостоятельно созданная версия - куча, выставленная на весь тариф. -Xmx4G внутри контейнера на 4 ГБ будет убит, потому что JVM нужна память вне кучи: под стеки потоков, metaspace, прямые байтовые буферы, кеш кода JIT и собственные структуры сборщика. Ставьте -Xmx примерно на 80-85% лимита контейнера, оставляя как минимум 512 МБ свободными и целый гигабайт для всего, что с модами. Полный набор флагов есть в статье флаги JVM для Minecraft и версии Java, а лимиты памяти Node.js - та же проблема для приложений, у которых свой отдельный потолок.

Затем идите по порядку, потому что самые дешёвые исправления стоят первыми:

  1. Сверьте настройку кучи с лимитом контейнера. Больше серверов убивает неверно настроенная куча, чем настоящая нехватка, и исправление ничего не стоит.
  2. Уменьшите то, что загружено. Снизьте дальность прорисовки и симуляции, сузьте границу мира, генерируйте заранее, а не на лету, очистите накопившиеся сущности. Каждый не удерживаемый чанк - это память, которая вам не нужна.
  3. Найдите утечку, прежде чем кормить её. Память, которая бесконечно растёт при постоянной нагрузке, - это плагин или мод, а больший тариф лишь сдвигает срок.
  4. Затем покупайте память. Это единственная проблема, которую память действительно решает.

В статье CPU или RAM: что на самом деле тормозит ваш сервер отделён этот случай от того, когда график памяти - ложный след, а своп Linux и убийца OOM объясняет, что на самом деле делает ядро.

Падение из-за собственных файлов#

Если есть трассировка стека, читайте её вверх, а не с конца. Последняя строка - место, где процесс сдался; причина обычно на десять-сорок строк выше, и это первая строка, называющая то, что установили вы, а не то, что поставляется с игрой. В трассировке Java идите по цепочке Caused by: до самого низа - последняя и есть корень.

code
[21:14:07] [Server thread/ERROR]: Could not pass event PlayerJoinEvent to ShopPlus v3.2java.lang.NoSuchMethodError: org.bukkit.inventory.ItemStack.getItemMeta()    at net.example.shopplus.JoinListener.onJoin(JoinListener.java:64)    ...Caused by: java.lang.ClassNotFoundException: com.example.vaultapi.Economy

Читается это так: плагин ShopPlus сломался, потому что был скомпилирован под другую версию игры, и потому что не установлена нужная ему зависимость. Ни один из этих фактов не в последней строке.

Четыре вещи, которые порождают такой класс перезапусков:

  • Несовпадение версий после обновления. Игра обновилась, моды нет. Это самый частый цикл падений на свете, и поэтому сервер с модами никогда не должен обновляться автоматически в день патча. Храните копию рабочей папки модов. Восстановление описано в статье что делать, когда обновление мода всё ломает.
  • Два мода, которые не ладят. Обычно это видно по исключению, называющему оба, или по падению, которое происходит только при установке конкретной пары.
  • Отсутствующая зависимость. API прав или экономики, которое плагин считает установленным.
  • Повреждённый регион мира или сохранение. Признак - воспроизводимое падение в один и тот же момент: когда заходит конкретный игрок, когда загружается конкретный чанк или во время сохранения после конкретного события. Восстанавливайте из backup, а не отлаживайте, а в статье backup, который действительно восстанавливается объясняется, почему имеющийся у вас backup может таким не быть.

Чтобы найти виновника среди сорока модов, делите пополам, а не гадайте. Уберите всю папку в сторону, убедитесь, что сервер стартует чисто, затем верните половину и запустите. Пять перезапусков сужают сорок кандидатов до одного, и это занимает около пятнадцати минут. Гадание занимает вечер.

Перезапуски, которые вы просили и забыли#

Удивительно большая доля обращений «мой сервер постоянно перезапускается» - это расписание. Проверьте всё это, прежде чем делать вывод, что что-то не так:

  • Собственные расписания панели. На RE:NODE они на вкладке Schedules: выражение cron и упорядоченный список задач с задержками, среди которых может быть и действие питания. Перезапуск, добавленный полгода назад, всё ещё работает. В статье выражения cron простыми словами разобрано чтение выражения, а задачи по расписанию, которые стоит иметь - что там должно быть.
  • Плагин или мод перезапуска внутри игры. Многие сообщества ставят такой и забывают. У него будет свой конфиг и своё расписание, не связанные с панелью.
  • Watchdog. В spigot.yml у Paper есть settings.timeout-time (по умолчанию 60 секунд) и settings.restart-on-crash, и тик, превысивший тайм-аут, заставляет watchdog убить и перезапустить сервер с записью The server has stopped responding! в логе. Это не падение, а зависание, которое считают падением, и исправлять нужно то, что заставило тик длиться минуту.
  • Обновление при запуске. Контейнер, который при каждой загрузке тянет последнюю сборку, будет чисто крутиться в цикле, если последняя сборка сломана. Зафиксируйте версию на время диагностики.
  • Менеджер процессов на вашей собственной машине. Юнит systemd с Restart=always или политика Docker --restart unless-stopped будут бесконечно перезапускать процесс, который не может стартовать, а причина будет каждый раз пролетать мимо.

На RE:NODE есть журнал активности по каждому серверу, в котором записаны действия питания и кто их вызвал. Это самый быстрый способ ответить на вопрос «его что-то перезапустило или он умер сам». Перезапуск, о котором вы просили, и тот, что сервер сделал сам, в консоли выглядят одинаково, а в журнале совершенно различны.

Игра сдаётся: учётные данные, версии и порты#

Такие сбои случаются до строки готовности или ровно раз за сессию, и после выявления все они скучны.

  • Истёкшие или отозванные учётные данные. CS2 и Unturned нужен токен входа игрового сервера Steam, FiveM - ключ Cfx.re, Don't Starve Together - токен Klei, BeamMP - ключ авторизации. Steam удаляет токен, которым долго не пользовались, а токен, привязанный к забаненному серверу, отзывается, так что сервер, проработавший год, может за ночь потерять возможность выходить в публичный список, хотя на вашей стороне ничего не менялось. Создание и замена токена разобраны в статье токены игровых серверов Steam.
  • Несовпадение версии с клиентом. Сервер обновился, а моды нет, либо обновился клиент, а сервер нет. Сервер обычно работает нормально, но никто не может подключиться, - это уже другая жалоба, которая приходит как тот же тикет.
  • Порт уже занят. java.net.BindException: Address already in use или FAILED TO BIND TO PORT! в Minecraft. В панели это почти всегда означает, что предыдущий процесс не успел полностью завершиться до следующего запуска, что лечится полной остановкой и паузой, либо что двум серверам случайно выдали один и тот же порт.
  • EULA. Свежий сервер Minecraft записывает eula.txt и выходит с кодом 0, пока не выставлено eula=true. Два чистых выхода подряд без ошибки - это всегда оно.
  • Полный диск. Сервер, который не может писать, не может и сохраняться, а многие игры падают, а не продолжают работу. Проверяйте диск прежде всего остального; это одна команда, и в консоли это невидимо до момента, когда становится фатальным.
bash
$ df -h /home/container$ du -sh /home/container/* | sort -h | tail -10

Циклы падений и что с ними делает хост#

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

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

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

Сервер, упёршийся в 100% CPU, приостановлен не будет. Контейнер ограничивается до купленной доли, поэтому он работает медленно, а не ломается, - мы пишем это в предупреждении, а не позволяем красному графику намекать на обратное.

Разрываем цикл: порядок действий#

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

  1. Остановите сервер правильно. Не Restart. Цикл, который вы поставили на паузу, - это проблема, которую можно прочитать.
  2. Сделайте backup, прежде чем что-либо трогать. Диагностика включает перемещение файлов, а перемещение файлов включает их потерю.
  3. Скопируйте консоль. Сто строк перед первым перезапуском, а не перед последним. Последний перезапуск - наименее информативный пример проблемы. В статье чтение консоли сказано, что стоит сохранять.
  4. Проверьте диск и память. Один df -h, один взгляд на график памяти за две минуты перед смертью. Эти две проверки исключают тихие причины и занимают тридцать секунд.
  5. Выключите всё, что его перезапускает. Расписание панели, плагин перезапуска, restart-on-crash. Нельзя прочитать цикл, который сам себя перезапускает.
  6. Запустите его без ничего добавленного. Папка модов убрана, конфиг возвращён к умолчаниям, плагины вынуты. Если запустился - проблема в том, что вы убрали. Если нет - проблема в мире, версии среды выполнения или машине.
  7. Проверьте со свежим миром. Это за один запуск отделяет повреждённое сохранение от сломанной установки, и именно эту проверку люди пропускают часами.
  8. Возвращайте по половине. Делением пополам.
  9. Откройте тикет с приложенной консолью. На RE:NODE тикет из панели доходит до всех сотрудников и принимает приватные вложения, а это правильное место для лога, в котором есть токен.

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

FAQ#

Мой сервер перезапускается, а в логе ничего нет. Что это?

Почти наверняка лимит памяти контейнера. Процесс, убитый сигналом SIGKILL, не может выполнить никакого кода, включая собственный логгер, так что консоль просто останавливается. Подтвердите по коду выхода - 137 - и по графику памяти, который непосредственно перед этим покажет вертикальный подъём до лимита.

Как отличить падение от перезапуска, запущенного кем-то?

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

Остановит ли перезапуски больший тариф?

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

Хорошая ли идея - автоматический перезапуск каждую ночь?

Для большинства серверов да. Он очищает медленное накопление, предсказуемо применяет обновления и переносит неизбежный перерыв на выбранное вами время, а не на то, которое выберет случай. Ставьте его на время, когда никто не играет, и предупреждайте людей заранее. Как сделать это, никого не потеряв, описано в статье расписания перезапусков, которые помогают.

Почему мой сервер приостановили за перезапуски?

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

Сервер перезапускается ровно в одно и то же время каждый день. Где искать?

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


Комментарии

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

0/2000