TeaHost
Minecraftminecraftsparkлагиоптимизацияпрофайлер5 мин. чтения

Профайлер Spark в Minecraft: поиск причин лагов

Spark профайлер Minecraft: установка, команды /spark profiler и /spark tps, чтение отчёта и поиск плагина или механики, которая съедает время тика

Кратко

Spark показывает, на что уходит время каждого тика сервера Minecraft. Начните с /spark tps и смотрите MSPT, а не TPS: медиана выше 40 мс — системная перегрузка. В пик лагов запустите /spark profiler start --timeout 120 --only-ticks-over 100 и разберите дерево вызовов сверху вниз. В Paper 1.21+ Spark уже встроен.

Классическая ситуация: TPS падает до 14, в чате жалобы, а вы по очереди выключаете плагины и надеетесь угадать. Spark — профайлер Minecraft, который убирает угадывание совсем: он показывает, сколько миллисекунд каждого тика уходит в конкретный метод конкретного плагина или в ванильную механику.

Ставится за минуту, работает на Paper, Fabric, Forge и на прокси, а отчёт открывается в браузере обычной ссылкой. Дальше — как им пользоваться на практике.

Установка

Начиная с версии 1.21 Paper поставляется со встроенным Spark — ставить ничего не нужно, это предпочтительный способ профилирования по документации PaperMC. Для Spigot, старых версий, Fabric и Forge скачайте сборку под своё ядро с сайта разработчика (lucko) и положите файл в plugins/ для Bukkit-платформ или в mods/ для Fabric и Forge. Перезапуск — и всё.

Проверка:

код
/spark

Если консоль отвечает списком подкоманд, плагин жив. Права: spark для всего, spark.profiler и spark.tps по отдельности, если раздаёте доступ модераторам через LuckPerms.

Важный момент: Spark сам почти не нагружает сервер. Его можно держать постоянно включённым на проде, в отличие от старых профайлеров вроде Timings, которые заметно искажали картину.

Первый взгляд: TPS и MSPT

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

код
/spark tps

Ответ выглядит примерно так:

код
TPS from last 5s, 10s, 1m, 5m, 15m:
 20.0, 19.98, 18.4, 17.9, 19.1
Tick durations (min/med/95%ile/max ms) from last 10s, 1m:
 8.2 / 12.4 / 31.7 / 210.4
CPU usage from last 10s, 1m, 15m:
 34%, 41%, 38% (system)

Читать надо MSPT, а не TPS. TPS — производная величина, он показывает 20.0 до тех пор, пока средний тик укладывается в 50 мс. Медиана 12 мс при максимуме 210 мс означает, что сервер в целом здоров, но раз в несколько секунд что-то намертво его подвешивает — и вот это «что-то» и надо ловить.

Если медиана уже 40+ мс, у вас не всплески, а системная перегрузка: слишком много сущностей, слишком большой view-distance или мало ядер.

Дополнительно:

код
/spark health --memory
/spark gcmonitor

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

Запуск профайлера Spark на сервере Minecraft

Основной сценарий:

код
/spark profiler start --timeout 120

Профайлер соберёт данные за две минуты и автоматически выдаст ссылку. Запускайте в момент пиковой нагрузки, когда лаги реально есть — профиль пустого ночного сервера бесполезен.

Полезные ключи:

  • --only-ticks-over 100 — записывать только тики длиннее 100 мс. Идеально для ловли редких фризов: в отчёт не попадёт обычная работа, останутся одни всплески.
  • --thread * — профилировать все потоки, а не только главный. Нужно, когда подозреваете асинхронный плагин или чанк-генерацию.
  • --alloc — профилировать не время, а выделение памяти. Так находят плагины, которые создают мусор мегабайтами и провоцируют GC.
  • --interval 2 — интервал сэмплирования в миллисекундах, по умолчанию 4. Мельче даёт точнее, но тяжелее.

Остановить раньше срока:

код
/spark profiler stop

Как читать отчёт

Открывается ссылка вида spark.lucko.me/xxxxxxx, и там дерево вызовов, отсортированное по доле времени. Первое, что нужно сделать — переключиться в режим Merge modes → Separate parent calls и включить Only ticks over, если использовали соответствующий флаг.

Дальше идёте сверху вниз и раскрываете самые толстые ветки. Что обычно находится:

ServerLevel.tickNonPassenger с большим процентом — мобы и сущности. Дальше внутри будет видно, кто именно: Mob.aiStep (поиск пути), Villager.tick (жители, самые дорогие мобы в игре), Item.tick (валяющийся дроп). Лечится лимитами спавна и entity-activation-range.

ChunkMap.tick и ChunkGenerator — генерация чанков. Значит, игроки исследуют новые территории. Помогает прегенерация мира через Chunky и снижение view-distance.

LevelChunk.tickBlockEntity — тайл-энтити: сундуки, воронки, печи. Классический источник лагов на серверах с большими автоматическими фермами. Смотрите HopperBlockEntity — если он в топе, крутите ticks-per.hopper-transfer в spigot.yml.

Имя пакета плагина прямо в дереве — например ru.example.myplugin.Listener.onMove. Это самый приятный вариант: виновник назван по имени. Смотрите, на каком событии он висит. PlayerMoveEvent с тяжёлой логикой внутри — почти всегда криво написанный плагин, потому что событие вызывается десятки раз в секунду на каждого игрока.

SQL, JDBC, HikariCP в главном потоке — плагин лезет в базу синхронно. Каждый запрос блокирует весь сервер. Ищите в конфиге плагина опцию асинхронного режима либо меняйте плагин.

Что делать с находкой

Порядок действий после того, как виновник найден:

  1. Проверить версию плагина. Половина проблем чинится обновлением — авторы регулярно оптимизируют горячие пути.
  2. Заглянуть в конфиг: у большинства тяжёлых плагинов есть интервалы проверок, радиусы и кэши, которые по умолчанию выставлены агрессивно.
  3. Отключить плагин на час и снять профиль заново. Если MSPT упал — подтверждено, если нет — вы поймали следствие, а не причину.
  4. Только потом лезть в ванильные конфиги.

Про сущности стоит помнить одну вещь: даже идеально настроенный сервер не вытянет ферму железа на десять тысяч жителей. Иногда правильный ответ — не оптимизация, а правило на сервере.

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

Почему Spark показывает 20 TPS, а игроки жалуются на лаги?

Значит, лагает не сервер, а сеть или клиент. Проверьте /spark ping — он покажет пинг игроков с сервера. Если пинги нормальные, а рывки есть, смотрите в сторону клиентских модов и дальности прорисовки у самих игроков.

Чем Spark лучше Timings?

Timings собирает статистику по событиям и задачам плагинов, то есть видит только то, что проходит через API Bukkit. Spark сэмплирует реальный стек JVM, поэтому видит и ванильный код, и внутренности плагинов. На Paper 1.21 Timings объявлен устаревшим и отключён по умолчанию.

Можно ли профилировать прокси?

Да, Spark ставится на BungeeCord и Velocity так же, как на бэкенд. Правда, на прокси лаги почти всегда сетевые, и полезнее будет /spark health, чем сэмплер. Про настройку самого прокси разговор отдельный.

Итог

Рабочий цикл: /spark tps для оценки, /spark profiler start --timeout 120 --only-ticks-over 100 в пик, разбор дерева сверху вниз, точечное исправление, повторный замер. Не меняйте пять вещей сразу — иначе не поймёте, что именно помогло.

Общие рекомендации по разгону собраны в гайде по оптимизации сервера. Если же профиль упорно показывает упор в CPU, а онлайн растёт — вопрос решается железом, посмотрите тарифы.