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

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

Сервер тормозит, TPS пляшет в районе 14, в чате жалобы на "лаги", а ты сидишь и не понимаешь, кто именно жрёт тик. Раньше открывал /timings paste и через минуту знал виновника. Сегодня Timings внутри Paper фактически мёртв (отключён по умолчанию с 1.20.5, выпилен в 1.21+), а Aikar's Timings v2 как отдельный продукт давно не развивается. На замену пришёл Spark от lucko, и за последние два года он стал стандартом отрасли: его рекомендует команда PaperMC, его упоминают в багрепортах Mojang, его поддерживают авторы Purpur, Folia, Fabric и большинства крупных модпаков.

Эта статья показывает, как поставить Spark в 2026 году, как снять полезный профиль с продакшена, как читать flame-graph, не превращаясь в шамана, и как из дерева вызовов вытащить конкретного виновника падения TPS, будь то плагин, чанк или сборка мусора.

Что такое Spark и почему он вытеснил Timings

Spark, это сэмплирующий профайлер для JVM, заточенный под Minecraft. Он не инструментирует код, как старый Timings, а с фиксированной частотой делает снимки стека всех потоков сервера. Из этих снимков строится дерево вызовов и flame-graph, по которому видно, где сервер реально проводит CPU-время.

Ключевое отличие от Timings: Spark показывает не "сколько тиков заняла обработка событий плагина X", а "какие именно методы и в каком стеке грелись на CPU". Это даёт честную картину, включая то, что Timings никогда не видел: внутренние методы Mojang, тяжёлые операции внутри плагинов, лямбды, нативный код, GC-паузы.

Почему Timings ушёл со сцены, понятно. Он был встроен в Paper, тащил накладные расходы, замерял только то, что специально обернули таймером, искажал картину при асинхронном коде и плохо ловил GC. С Paper 1.20.5 команда отключила Timings по умолчанию, в 1.21 удалила полностью. Spark при этом работает на любой версии от 1.8 до 1.21.x, на Spigot, Paper, Folia, Fabric, Forge, NeoForge, Velocity и BungeeCord.

Автор Spark, lucko, разработчик LuckPerms. Spark разрабатывается открыто на github.com/lucko/spark, официальный сайт spark.lucko.me, плагин раздаётся через Hangar (hangar.papermc.io/lucko/spark) и Modrinth (modrinth.com/plugin/spark). На апрель 2026 актуальна ветка 1.10.x, поддерживается Java 21 и серверы вплоть до 1.21.5.

Установка на разные платформы

Spark поставляется как один универсальный JAR с автодетектом платформы, плюс отдельные сборки для Fabric и Forge. Скачивай с spark.lucko.me/download или с Modrinth, не с reupload-сайтов.

Spigot, Paper, Purpur, Folia. Кидаешь spark-1.10.x-bukkit.jar в plugins/ и перезапускаешь сервер. После старта команда /spark доступна по праву spark. По умолчанию доступ только у operator-ов, для не-OP игроков выдай право через LuckPerms: lp user <name> permission set spark true.

Velocity. Для прокси нужен spark-1.10.x-velocity.jar, кладёшь в plugins/ Velocity-прокси. На прокси Spark особенно полезен, чтобы ловить лаги в обработке Plugin Messages, при подключении игроков, в работе LiteBans и подобных тяжёлых плагинов.

BungeeCord и Waterfall. Есть отдельный spark-1.10.x-bungeecord.jar. Команды те же, флаги те же. Имей в виду, Bungee/Waterfall в 2026 уже legacy, миграция на Velocity рекомендована.

Fabric. Quilt и Fabric используют spark-1.10.x-fabric.jar, кладёшь в mods/. Зависит от Fabric API. Если играешь на сервере, ставь только серверную версию мода, для клиента есть отдельная сборка spark-fabric-client.

Forge и NeoForge. Forge версии 1.20.1 и старше: spark-1.10.x-forge.jar в mods/. Для NeoForge 1.20.4+ есть отдельный JAR spark-neoforge. Команды те же, доступ через /spark от имени оператора, права через FTB Ranks или OpenPartiesAndClaims.

Sponge. Поддерживается через spark-1.10.x-sponge.jar. На SpongeForge ставится в mods/, на SpongeVanilla в plugins/.

После установки проверь работу командой /spark, она выведет справку. Если выдаёт "unknown command", смотри в latest.log: плагин может ругаться на старый Java (нужен 17+, рекомендован 21).

Базовые команды: /spark profiler, /spark tps, /spark health

Spark, это набор подкоманд под общим /spark. Разберёмся с теми, что используются 95% времени.

/spark tps

Показывает текущий TPS и MSPT (миллисекунды на тик), разбитый по интервалам:

TPS from last 5s, 10s, 1m, 5m, 15m:
  *14.2, *16.8, 19.4, 19.8, 19.9
Tick durations (min/med/95%ile/max ms) from last 10s, 1m:
  3.2 / 12.4 / 48.1 / 220.5

Звёздочка перед числом, это значение ниже целевого. 95-й процентиль миллисекунд на тик, самая полезная цифра: показывает не средний MSPT, а тот, что был хуже, чем у 95% тиков. Если 95%ile стабильно выше 50ms, у тебя проблема, даже когда средний TPS красивый.

/spark profiler

Главная команда. Запускает сэмплирующий профайлер, по умолчанию на основном потоке сервера. Без аргументов работает до тех пор, пока не остановишь руками через /spark profiler stop.

/spark profiler start
... ждём 60-300 секунд во время лагов ...
/spark profiler stop

По остановке Spark загружает результат на bytebin (свой публичный pastebin для бинарных дампов) и кидает в чат ссылку вида https://spark.lucko.me/abc123def. Открываешь её в браузере и работаешь с интерактивным viewer-ом.

Полезные флаги:

  • --timeout 120, авто-остановка через 120 секунд. Удобно, когда лагает регулярно.
  • --thread *, профилировать все потоки JVM, а не только Server Thread. Нужно при подозрении на async-плагины, GC и Netty.
  • --only-ticks-over 100, сохранять стеки только тех тиков, что заняли больше 100ms. Голден-режим для редких фризов посреди нормального TPS.
  • --interval 10, семплинг с интервалом 10ms (по умолчанию 4ms). Снижает нагрузку на длинных профилях.

/spark health

Свежая команда, заменила старый /spark tickmonitor. Быстрый обзор JVM:

Server Health Report:
  TPS: 18.4 (last 5s)
  CPU: 64% (process), 82% (system)
  Memory: 8.4G / 12G heap
  GC: G1 Young 12 collections, 340ms total
  Disk: /world 240G free of 500G

Если system CPU высокий, а process CPU низкий, на машине кто-то ещё ест CPU, типичный кейс шаред-хостинга.

/spark heapsummary и /spark heapdump

/spark heapsummary, лёгкий снимок: сколько объектов каждого класса в куче и сколько они весят. Хватает, чтобы поймать утечку памяти у плагина: видишь org.bukkit.craftbukkit.v1_21_R1.entity.CraftItem в количестве 480000, и понимаешь, кто-то не очищает дропы.

/spark heapdump, полноценный hprof-дамп для VisualVM или Eclipse MAT. Использовать только когда heapsummary не дал ответа: дамп пишется на диск, может занимать гигабайты, и на время записи сервер встаёт колом.

/spark gc

Статистика сборщика мусора с момента старта. Полезно сравнить, сколько времени JVM провела в GC-паузах против полезной работы. Цифра выше 5%, плохая новость, выше 15%, пора чинить флаги Java или искать утечку.

Чтение flame-graph: Self time vs Total time

Graph viewer на spark.lucko.me, перевёрнутый flame-graph: корень дерева сверху, листья снизу. Каждый прямоугольник, метод, ширина пропорциональна времени, потраченному в этом методе. Чем шире, тем горячее.

Total time включает время, проведённое в самом методе и во всех его вызовах. У корня дерева Total всегда 100%. Полезен, чтобы выбрать ветку, которая целиком тянет CPU.

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

Практическое правило: смотришь Total, чтобы выбрать ветку ("60% времени уходит в ChunkMap.tick"), переключаешься на Self time и идёшь вниз по ветке, ища, где Self становится максимальным. Этот лист, конкретная функция, в которой проблема.

Spark подкрашивает прямоугольники по типу кода: Mojang/NMS один цвет, плагины другой, JVM третий. Включи в настройках viewer-а "Colour by source", и сразу увидишь, что 40% тика жрёт один конкретный плагин на красном фоне. Ctrl+F открывает поиск по имени метода, можно искать по пакету (com.discordsrv), классу (AsyncCatcher) или имени метода. Кнопка "Sources" группирует всё дерево по источнику, сразу видно top-3 виновника.

Типичные виновники лагов и как их видно в Spark

Загрузка и генерация чанков. В дереве это ServerLevel.tick -> ChunkMap.tick -> ChunkGenerator.generate. Если эта ветка съедает 30%+ Total time, виноваты либо игроки, исследующие новые территории, либо плагин, который грузит чанки сам (динмап, AntiAFK телепорты, рекламные плагины с автотп). Решение: предгенерация мира через Chunky, ограничение view-distance до 8-10, отключение принудительной загрузки чанков в сторонних плагинах.

Тик-лист сущностей. Ветка EntityTickList.forEach -> Mob.tickAi -> PathFinder.findPath. Если поиск пути жрёт 20%+, у тебя где-то застрявшие мобы (типичный кейс, забитый загон с коровами) или жители со сломанным AI. Лечится /spark profiler --only-ticks-over 100, потом kill @e[type=cow,distance=..200] для конкретных загонов или включением Lobotomize villagers в Purpur.

Редстоун. ServerLevel.tickBlock -> RedstoneWireBlock.updateState. Эта ветка любит вспыхивать у больших технических серверов. Решение: redstone-implementation: ALTERNATE_CURRENT в paper-world-defaults.yml, замена тактовых генераторов на наблюдателей или сравниватели.

Сборщик мусора. GC видно как широкие прямоугольники в потоках G1 Young Gen, G1 Concurrent, ZGC Concurrent. Если профиль с --thread * показывает, что GC занимает 10%+ wall-clock, флаги Java неправильные или у тебя просто мало RAM. Перепроверь -Xms равен -Xmx, попробуй G1 с aikar-флагами или ZGC на Java 21.

Плагин-плохиш. Классика: вешаешь --thread * и видишь, что один плагин в потоке pool-7-thread-1 стабильно жрёт CPU и делает Socket.connect, JDBC.executeQuery или URL.openStream. Это и есть тот самый "асинхронный" плагин, который ходит на внешний API на каждый event. Ищи имя плагина в стеке, отключай или ругай автора.

Авто-сейв. Каждые 5-10 минут в профиле всплывает большой Self time у ChunkSerializer.write и RegionFile.write. Это нормально, но если на авто-сейве TPS падает с 20 до 10, диск медленный (HDD вместо NVMe), либо мир слишком большой и пора paper trim или chunky trim.

Как поделиться отчётом

Как только профайлер останавливается, в чате/консоли появляется ссылка на bytebin типа https://spark.lucko.me/abc123def. По этой ссылке любой человек видит интерактивный viewer.

Что стоит знать:

  • Ссылки на bytebin живут долго, но не вечно. Если профиль нужен надолго, скачай .sparkprofile файл из viewer-а кнопкой "Download".
  • Профили публичные, по ссылке открываются без пароля. В дамп попадают имена пакетов, классов и методов, иногда имена игроков (через лямбды), иногда конфиденциальные пути файлов.
  • В viewer-е есть кнопка "Anonymize". Включает замаскированные имена игроков и обезличенные пути.

Для поддержки от авторов плагинов: bytebin-ссылка, это то, что у тебя попросят на Discord-сервере PaperMC, EssentialsX или любого крупного плагина. Не надо постить скриншоты, не надо выдёргивать строки из логов.

Cheatsheet команд Spark

КомандаЧто делаетКогда использовать
/spark tpsТекущий TPS + MSPT по интерваламБыстрая проверка, есть ли проблема
/spark profiler startЗапуск профайлераДиагностика лагов на основном потоке
/spark profiler stopОстановка + загрузка отчётаПосле сбора достаточного семпла
/spark profiler --timeout 120Авто-стоп через 120 секКогда не хочется возвращаться вручную
/spark profiler --thread *Все потоки JVMПодозрение на async-плагины, GC, Netty
/spark profiler --only-ticks-over 100Только тики дольше 100мсРедкие фризы при нормальном TPS
/spark profiler --interval 10Семплинг с интервалом 10мсСнизить нагрузку на длинных профилях
/spark profiler infoСтатус текущего профилированияПроверить, идёт ли запись
/spark profiler cancelОтмена без отчётаПередумал собирать
/spark healthЗдоровье JVM: CPU, RAM, GC, дискПервый взгляд при жалобах на лаги
/spark heapsummaryЛёгкий снимок объектов в кучеПоиск утечек памяти
/spark heapdumpПолный hprof-дамп на дискГлубокий разбор утечек в VisualVM/MAT
/spark gcСтатистика сборщика мусораДиагностика GC-проблем
/spark pingПинг игроков с сервераСетевая диагностика
/spark activityЛог активности плагиновЧто и кем было запущено недавно

Продвинутые опции

Сравнение профилей. В viewer-е есть кнопка "Compare", даёт diff между двумя профилями. Полезно после оптимизации: снимаешь "до" и "после", смотришь, какая ветка действительно ушла. Иногда видно, что починил одно, но утяжелил другое: отключил динмап, но Essentials стал чаще писать на диск.

Профилирование Folia. Folia, многопоточный форк Paper, имеет несколько Region Threads. Spark корректно ловит каждый, в viewer-е они показаны отдельными деревьями. На Folia особенно полезен --only-ticks-over, чтобы поймать, какой регион отстаёт.

Конфиг spark.yml. В plugins/spark/config.json можно настроить URL bytebin (для своего инстанса), отключить публичные ссылки (viewer-url-only-private: true), включить автоматический сбор профиля при падении TPS ниже порога:

{
  "profiler": {
    "auto": {
      "enabled": true,
      "trigger-tps": 10.0,
      "duration": 90
    }
  }
}

С такой настройкой Spark сам поймает следующий фриз, не нужно сидеть и ждать.

REST API. Spark публикует REST API через bytebin, можно автоматизировать сбор и хранение профилей. У lucko есть пример скрипта в репозитории, удобно для крупных сетей.

Сравнение с Timings и Aikar's Timings v2

ПараметрTimings (Paper)Timings v2 (Aikar)Spark
Статус в 2026Удалён в Paper 1.21+Не развиваетсяАктивно развивается
МетодИнструментированиеИнструментированиеСэмплирование
Ловит NMS кодОграниченноОграниченноПолностью
Async потокиНетЧастичноПолностью
Ловит GC-паузыНетНетДа
Накладные расходыСредниеСредниеНизкие (1-2%)
Поддержка FoliaНетНетПолная
Fabric/ForgeНетНетПолная
Поделиться отчётомtimings.aikar.cotimings.aikar.cospark.lucko.me
Сравнение профилейНетНетДа
Heap-анализНетНетДа

Практический вывод. Если у тебя ещё стоит Timings (на Paper 1.20.4 или ниже), переходи на Spark прямо сейчас. Параллельно держать Timings нет смысла, накладные расходы суммируются. Aikar's Timings v2 как отдельный продукт можно забыть, его автор сам перешёл на Spark и рекомендует его в гайдах по флагам Java.

FAQ

Spark тормозит сервер?

Сэмплирующий профайлер по умолчанию шлёт ~1% накладных расходов CPU на интервале 4ms. Это меньше, чем стоил Timings в активном режиме. На профиле длиннее 5 минут разница в TPS не выходит за статистическую погрешность.

Можно ли держать Spark постоянно?

Да, и многие так делают. Сам по себе плагин ничего не профилирует, пока не запустишь команду. Накладные расходы простаивающего Spark близки к нулю. /spark health тоже работает в фоне без записи стеков.

Что делать, если bytebin недоступен?

Можно скачать профиль локально кнопкой --save-to-file или загрузить на свой инстанс bytebin (исходники открыты на GitHub lucko). Локальный viewer тоже есть: открываешь скачанный .sparkprofile файл прямо в браузере на spark.lucko.me, он не загружается на сервер.

Spark покажет DDoS?

Нет. Spark, профайлер CPU и памяти Java, он смотрит, что делает сам сервер. Внешнюю сетевую нагрузку (UDP-флуд, бот-атаки на login) он не видит. Для защиты от DDoS нужна сетевая фильтрация перед сервером, как у MineGuard, Spark лишь покажет, что в твоих лагах виноват не плагин, а внешний фактор.

Какой профиль слать автору плагина в баг-репорте?

Минимум 60 секунд работы во время реальной нагрузки, флаги --thread *, плюс /spark health снапшот. Если проблема редкая, добавь --only-ticks-over 100. Опиши версию сервера, версию плагина и количество онлайна на момент снимка.

Подходит ли Spark для клиента?

Да, есть отдельные сборки spark-fabric-client и spark-forge-client. Полезно для модпак-разработчиков и стримеров, чтобы понять, какой мод дёргает FPS. Команды на клиенте те же, вызываются через keybind или чат.

Если после получасового изучения flame-graph ты упёрся в стену "всё горит, и непонятно", это нормально, профилирование, навык. Снимай профили регулярно, сравнивай до и после изменений, копи насмотренность. Через десяток отчётов начнёшь узнавать ChunkMap.tick и SpongeRedstone издалека. Главное помни: Spark покажет внутренние тормоза, но если лаги от внешней нагрузки (бот-атака, UDP-флуд, синтетический пинг), профайлер будет молчать, потому что виноват не сервер, а сеть, и тут нужна уже сетевая защита уровня MineGuard, а не дальнейшее ковыряние в коде.


Proteja Seu Servidor de Ataques DDoS

Proteção gratuita com configuração em 5 minutos. 1 TB de tráfego incluso.

Experimentar Grátis


Artigos Relacionados