Держать Minecraft-сервер просто — пока что-то не начинает тормозить и никто не может объяснить почему. ServerScope — ответ Etoryx на этот пробел: платформа мониторинга и наблюдаемости для серверов Paper и Folia, которая превращает состояние сервера в то, на что действительно можно смотреть — живые метрики, сохранённая история, оповещения, веб-панель и JSON API.
Это рассказ о том, как он проектировался и какие решения его сформировали.
Проблема невидимости состояния сервера
Большинство проблем с производительностью на Minecraft-сервере незаметны, пока не начинают мешать. Сервер чувствует себя нормально, затем подгружается чанк, подскакивает число сущностей или плагин делает слишком много работы во время события — и игроки внезапно замечают лаги.
Стандартные инструменты отвечают только на самый общий вопрос. Одно число тикрейта говорит, что что-то не так, но не где. Администратор остаётся гадать между мирами, чанками и плагинами и часто перезапускает сервер, просто чтобы убрать симптом, который так и не диагностировал.
ServerScope исходит из простой посылки: администратор должен иметь возможность посмотреть на сервер и понять его состояние — прямо сейчас и в динамике — без подключения внешнего профайлера и чтения сырых логов.
Что ставит целью ServerScope
Цель — операционная видимость на Paper и Folia, реализованная через несколько связанных подсистем, а не через одну команду:
- непрерывно собирать живые метрики и хранить ограниченную историю;
- диагностировать проблемы и поднимать оповещения с понятными уровнями важности;
- открывать всё через игровые команды, веб-панель и JSON API;
- оставаться достаточно дешёвым, чтобы работать в продакшене постоянно.
Инструмент мониторинга, который заметно ухудшает то, что он измеряет, провалился. Низкие накладные расходы — это функция, а не приятное дополнение.
Внутри архитектуры
ServerScope построен как набор взаимодействующих модулей, а не как монолит:
- Коллекторы непрерывно собирают операционные метрики.
- Хранилище сохраняет данные в SQLite — асинхронно, пакетно и с ограничением размера, чтобы записи не блокировали сервер, а база не росла бесконечно.
- Диагностика и оповещения анализируют собранные данные и формируют уведомления по уровням важности.
- Движок профилирования наблюдает за выбранным набором событий Bukkit/Paper.
- Веб-сервер отдаёт и панель, и JSON API.
Именно сохранение данных отличает живой показатель от настоящей наблюдаемости. Поскольку история живёт в SQLite (serverscope-mvp.db), а не только в памяти, тренды сохраняются и их можно изучить уже после того, как момент прошёл, — а не только взглянуть на них в реальном времени.
Совместимость с Paper и Folia
Folia меняет правила. Вместо одного основного потока сервер делится на регионы, которые тикают независимо в пуле потоков. Код, который предполагает один глобальный основной поток, на Folia не просто медленнее — он некорректен.
ServerScope относится к потокам как к первоклассной заботе, а не как к цели порта:
| Аспект | Paper | Folia |
|---|---|---|
| Планирование | Глобальный планировщик | Региональные / глобальный планировщики |
| Общее состояние | Один основной поток | Владение по регионам |
| Безопасный доступ | Основной поток | Поток региона-владельца |
Практическое правило плагина — никогда не читать и не изменять состояние сервера из неправильного потока и полностью убирать хранилище и веб-сервер с пути тиков. Он рассчитан на Paper или Folia 1.21+ и Java 21+.
Что плагин делает сегодня
Эти возможности есть в проекте в его нынешнем виде.
Он непрерывно собирает ключевые сигналы — TPS, MSPT, тренды численности сущностей, производительность чанков и профили выполнения событий плагинов. Движок профилирования наблюдает за событиями вроде player_interact, block_break, block_place, entity_damage, inventory_click и creature_spawn, отмечая медленные, частые или аномальные.
Когда что-то выходит за рамки, система оповещений реагирует по важности: оповещения CRITICAL доходят до админов в игре, а уведомления уровня WARN появляются в консоли и веб-интерфейсе — для условий вроде низкого TPS, высокого MSPT, избытка сущностей или необычной активности чанков.
Всё доступно тремя способами: через игровые команды, встроенную веб-панель и JSON API.
/serverscope
/serverscope status
/serverscope reload
/serverscope report
/serverscope findings
/serverscope alerts
/serverscope web regenerate-token
Веб-слой по умолчанию слушает 127.0.0.1:8080 и защищён автоматически сгенерированным токеном для каждого сервера (перевыпускается командой web regenerate-token). Он поддерживает CORS и обратные прокси, применяет настраиваемое ограничение частоты запросов и ограничивает ответы 2 МБ JSON. Доступ регулируется гранулярными правами вроде serverscope.admin и serverscope.alerts.
Ограничения и проектные решения
Большую часть работы определили два ограничения.
Первое — накладные расходы. Монитор, который нагружает сервер, противоречит собственной цели, поэтому дорогие части намеренно держатся вне горячего пути: записи в хранилище асинхронные, пакетные и ограниченные, а веб-сервер работает независимо от цикла тиков.
Второе — корректность на Folia. Поддержка регионной модели потоков — это не флаг, который включают; это допущение, проходящее через весь код. Закладывать его с самого начала оказалось гораздо дешевле, чем дорабатывать потом.
Безопасность получила такое же отношение — по умолчанию, а не задним числом: панель слушает localhost и требует токен из коробки, так что её публикация — это осознанный выбор, а не случайность.
Выводы и что дальше
Самый ясный вывод: наблюдаемость — это сохранение данных плюс сдержанность. Хранение ограниченной истории превращает мгновенный показатель в то, что действительно можно расследовать, а вынос каждого дорогого пути за пределы цикла тиков и делает это безопасным для живого сервера.
Если хотите прочитать код или попробовать его на своём сервере — и то, и другое открыто:
- Modrinth: ServerScope на Modrinth
- GitHub: Etoryx/ServerScope
Если вы планируете плагин или мод для Minecraft и хотите, чтобы его делали с той же заботой о накладных расходах и корректности на платформе, напишите мне — это именно то, чем занимается Etoryx.