Статус сервера
Экран Администрирование → Статус сервера показывает состояние инстанса ERP, который ответил на запрос. За балансировщиком соседние обновления могут попасть на разные узлы, поэтому в начале страницы всегда выводятся идентификатор инстанса и имя хоста.
Экран предназначен для оперативной диагностики. Большинство показателей живёт только в памяти процесса, сбрасывается при перезапуске и не заменяет долговременный мониторинг в Prometheus и журналах приложения.
Как устроен модуль
Основной снимок собирает ServerStateProvider, HTTP-операции обслуживает StateAction, а интерфейс построен на компоненте ServerState.vue.
Запрос без параметра action открывает страницу и возвращает поле state.
Снимок содержит компактные показатели, которые допустимо обновлять по таймеру. Объёмные данные запрашиваются отдельными операциями только при открытии соответствующего блока:
| Данные | Операция | Почему вынесены отдельно |
|---|---|---|
Сообщения компилятора |
|
Список может содержать сотни ошибок и предупреждений. |
Последние HTTP-запросы |
|
Журнал загружается страницами и сортируется на сервере. |
Пользователи и сессии |
|
На нагруженном инстансе список может быть большим. |
Стеки занятых соединений |
|
Текст стеков объёмный и нужен только при диагностике пула. |
История релизов и запусков |
|
Данные читаются из БД только на отдельной вкладке. |
На вкладке Состояние автообновление включено по умолчанию с периодом 10 секунд. Доступны интервалы 5, 10, 30 и 60 секунд; опрос выполняется только пока открыта эта вкладка и предыдущий запрос завершён.
Инстанс, сборка и JVM
Инстанс
Блок показывает:
-
идентификатор из
server.instance.id; если настройка отсутствует, для этого экрана используется имя хоста; -
имя хоста из
InetAddress.getLocalHost().getHostName(), а при ошибке — переменная окруженияHOSTNAME; -
HTTP-порт
server.port.http, по умолчанию 8080; -
порт метрик
server.telemetry.port, по умолчанию 9090.
Для портов экран сначала проверяет одноимённую переменную окружения и затем значение в Setup.
У telemetry exporter сейчас другой порядок: OpenTelemetryImpl читает только Setup.
Если порт метрик переопределён переменной окружения, экран может показать не тот порт, на котором действительно слушает exporter.
Сборка
Версия, номер сборки, коммит, ветка, время и ключи задач берутся из ru/bgcrm/version/update.properties.
Файл формируется задачей сборки; пустые значения означают, что модуль собран без генерации version info.
Ключи задач извлекаются на сборке из сообщений коммитов после ближайшего тега release-N.
Настройка jira.browse.url превращает ключи в ссылки; к её значению ключ дописывается без дополнительного разделителя.
JVM и приложение
Время запуска JVM и uptime берутся из RuntimeMXBean.
Время готовности приложения хранит AdminPortListener; разница между этими значениями показывается как длительность запуска ERP.
Также выводятся:
-
имя и версия JVM;
-
текущее, пиковое и daemon-число потоков;
-
число доступных процессоров;
-
JVM-аргументы.
Аргументы -D показываются как пары «свойство — значение», остальные — отдельным текстовым списком.
Экран не скрывает значения системных свойств, поэтому не передавайте секреты через -D пользователям, которым доступен статус сервера.
HTTP-запросы
WebRequestStatsListener подписан на WebRequestEndEvent и ведёт два независимых окна по 60 секунд:
-
рабочие запросы;
-
периодический клиентский опрос
/pool.do.
pool.do вынесен отдельно, потому что его отправляет каждая открытая вкладка ERP.
Если смешать его с рабочими обращениями, частота и среднее время ответа в первую очередь отражают число открытых вкладок.
Для рабочих запросов показаны:
-
частота и число обращений за текущее окно;
-
общее число после старта процесса;
-
среднее и максимальное время ответа за окно;
-
самый медленный запрос за окно;
-
число ответов со статусом
failureилиinvalid.
Пока инстанс работает меньше минуты, длина окна равна фактическому uptime listener, а не 60 секундам.
Журнал последних запросов
В памяти хранится до 500 последних запросов, кроме:
-
/pool.do; -
статических ресурсов — файлов, чьё имя содержит расширение, кроме
.doи.jsp.
Журнал очищается при перезапуске.
Он показывает время, HTTP-метод, endpoint, Struts action, telemetry status и длительность.
Ошибочными считаются только статусы failure и invalid; unknown в этот фильтр не входит.
Доступны все записи либо только ошибочные. Сортировка по времени, запросу, action, статусу и длительности выполняется до пагинации на сервере. Неизвестный ключ сортировки сохраняет исходный порядок от новых записей к старым.
Счётчики минутного окна учитывают все рабочие HTTP-запросы, включая статику, а журнал статику отбрасывает. Поэтому число строк журнала не обязано совпадать со счётчиком запросов.
Для анализа за период, группировки по endpoint и построения алертов используйте телеметрию.
Планировщик
Блок читает состояние текущего SchedulerEngines.active().
Списки задач относятся к конфигурационным задачам scheduler.task.<номер>.
Задачи из справочника Администрирование → Планировщик здесь списком не выводятся.
В сводке доступны:
-
значение
scheduler.start, по умолчанию запуск включён; -
число успешно загруженных блоков;
-
число блоков, которые не загрузились;
-
число выполняющихся задач.
activeTaskCount является общим для executor и включает также задачи из БД, хотя таблица текущих запусков ниже содержит только конфигурационные классы.
Для загруженной задачи можно открыть номер, полное имя класса, расписание и состояние. Пустое расписание означает запуск каждую минуту. Для незагруженной задачи выводится сохранённая причина ошибки. Отдельная таблица активных запусков показывает класс, время старта и текущую длительность.
Подробное устройство планировщика приведено на странице Планировщик.
Веб-сокеты
BaseWebSocket хранит открытые websocket-сессии текущего процесса.
Экран группирует их по path и показывает:
-
общее число сокетов;
-
число разных пользователей;
-
число зависших соединений;
-
давность самого старого ответа pong.
Ping отправляется каждые 30 секунд. Соединение считается зависшим, если после первого pong ответа нет больше 60 секунд; фоновая проверка затем закрывает такую сессию. До первого pong поле давности пустое и сессия не считается зависшей.
Одна пользовательская вкладка может открыть несколько websocket endpoints, поэтому число сокетов бывает больше числа пользователей.
Память и сборка мусора
Сводка памяти использует Runtime:
-
Занято под кучу — объём heap, уже выделенный JVM (
totalMemory), а не фактически занятые объектами байты; -
Предел — максимальный heap (
maxMemory); -
Свободно в куче — свободная часть уже выделенного heap (
freeMemory).
Таблица memory pools строится через MemoryPoolMXBean и показывает тип, текущее использование, предел и пик.
Значение -1 означает, что JVM не сообщает предел или показатель для этого пула.
Счётчики garbage collectors берутся из GarbageCollectorMXBean: число сборок и суммарное время после старта JVM.
Они монотонно растут, поэтому диагностировать паузы следует по разнице между обновлениями и по метрикам, а не по абсолютному значению.
Соединения с БД
Экран показывает все пулы ConnectionPool:
-
основной
master; -
настроенные
slave; -
настроенные
trash.
Для каждого пула выводятся занятые и свободные соединения, их пределы и загрузка. Состояние репликации заполнено только для slave: доступна ли реплика и отстаёт ли она от master.
Экран не выполняет проверочный SQL при каждом обновлении.
Он читает флаги ConnectionPool, которые обновляет задача контроля репликации.
Если эта задача не работает, статус может быть устаревшим.
Клиенты внешних API
ServerStateProvider ищет в локальном MBean server объекты домена BGCRM, у которых key property name начинается с api-.
Они группируются по клиенту и отображаются после первой инициализации соответствующих компонентов.
Состав атрибутов не зафиксирован экраном: он читает все атрибуты MBean.
Обычно это circuit breaker, rate limiter и connection pool.
Числовое состояние CircuitBreaker.state преобразуется в имя Resilience4j, например CLOSED.
Ошибка чтения одного MBean не прерывает весь снимок: компонент отображается с пустым набором показателей. Отсутствие клиента на экране означает, что его MBean ещё не зарегистрирован, а не обязательно ошибку конфигурации.
Плагины и динамический код
Список плагинов строится из текущего PluginManager и содержит id, название и версию.
Название и версия пусты у плагинов без JSON-описателя.
Для динамического кода показаны:
-
число исходников, найденных при последней полной компиляции;
-
число загруженных классов, включая вложенные и анонимные;
-
число исходников, для которых не найден загруженный класс;
-
число компиляций после старта;
-
тип, время, длительность, инициатор и цель последней компиляции;
-
число ошибок и предупреждений
javac.
Сообщения последней компиляции загружаются страницами по 25 строк; допустимый размер страницы — до 200. Сначала идут ошибки, затем предупреждения. При появлении ошибок список раскрывается автоматически.
Lifecycle компиляции и смысл показателей описаны на странице Динамический Java-код.
Диагностика
Данные этого блока не входят в автообновляемый снимок.
Пользователи и сессии
Список строится из локального LoginStat и показывает пользователя, время входа и последнюю активность каждой сессии.
Он относится только к текущему инстансу и не объединяется с другими узлами.
При наличии права StateAction:dropSessions можно пометить к сбросу выбранных пользователей или все сессии инстанса.
Пустой список id означает «все».
Сессия не удаляется из HTTP-контейнера немедленно.
Её id попадает в список отозванных, а пользователь выходит при ближайшей проверке сессии, обычно на следующем pool.do.
Связанные websocket-сессии закрываются после события истечения пользовательской сессии.
Стеки соединений пула
При db.trace=1 пул запоминает stack trace в момент выдачи каждого соединения и удаляет его после возврата.
По кнопке выводятся соединения, занятые в момент запроса, и места, где они были получены.
Пустой список означает, что сейчас соединений на руках нет.
Если трассировка выключена, сервер возвращает Pool trace is off. Check db.trace option.
db.trace читается при создании ConnectionPool, поэтому изменение настройки требует перезапуска приложения.
Трассировка добавляет расходы на снятие стеков и предназначена для временной диагностики утечек.
История релизов
После полной готовности сервера ReleaseHistoryService.registerStart() записывает запуск в master-БД.
Ошибка записи журналируется, но не останавливает приложение.
Таблица app_instance_start создаётся скриптом ru/bgcrm/state/repository/table.sql.
Одна строка содержит инстанс, хост, version info сборки и время фактического запуска.
Вкладка показывает два представления:
-
Сборки — записи, сгруппированные по версии, номеру сборки, коммиту и ветке, с первым и последним запуском, числом запусков и списком instance id;
-
Журнал запусков — отдельные строки в обратном хронологическом порядке.
Лимит применяется отдельно к обоим запросам. Интерфейс предлагает 50, 100 или 500 записей; backend принимает значения от 1 до 500 и использует 50 по умолчанию.
История общая для инстансов, которые пишут в одну master-БД. Она показывает то, что действительно запускалось, а не все артефакты, собранные CI.
Если таблицы нет, регистрация старта завершится ошибкой в серверном логе, а вкладка истории покажет ошибку. Пустая существующая таблица является штатным состоянием до первого успешного запуска после её установки.
Настройки
| Настройка | Назначение |
|---|---|
|
Идентификатор узла в сводке и истории запусков. |
|
Показываемый HTTP-порт, по умолчанию 8080. Для запуска сервера и экрана поддерживается одноимённая переменная окружения. |
|
Показываемый порт Prometheus exporter, по умолчанию 9090. Ограничение с переменной окружения описано выше. |
|
Разрешает запуск конфигурационного планировщика, по умолчанию |
|
Показывает блок лицензии из системных свойств |
|
Префикс ссылки на задачу в составе сборки. |
|
Включает сохранение stack trace для занятых соединений. Требует перезапуска. |
Права
Для модуля объявлены отдельные действия:
| Действие | Данные | Текущая настройка |
|---|---|---|
|
Основной экран и снимок состояния |
|
|
Пользователи и сессии |
|
|
Диагностика компилятора |
|
|
Журнал последних HTTP-запросов |
|
|
Стеки занятых соединений |
|
|
История релизов и запусков |
|
|
Сброс пользовательских сессий |
Отдельное право |
allowAll означает доступ любому авторизованному пользователю при включённой проверке прав, в том числе по прямому URL.
Пункт меню может быть скрыт проверкой права на action, но это не ограничивает прямой запрос к операциям с allowAll.
Из-за текущей конфигурации флаги sessionsAllowed и poolTraceAllowed всегда истинны для открывшего экран пользователя.
Кнопки сброса сессий появляются только при отдельном праве StateAction:dropSessions.
Границы данных
| Область | Что показывает экран |
|---|---|
Только ответивший процесс |
JVM, потоки, heap, GC, HTTP-окно и журнал, websocket-сессии, плагины, динамический код, JMX API-клиенты. |
Только ответивший инстанс |
Пулы соединений, конфигурационный планировщик, пользователи и сессии, stack traces соединений. |
Общая master-БД |
История релизов и запусков для всех инстансов, которые используют эту БД. |
При диагностике за балансировщиком сначала сверяйте server.instance.id и хост.
Для сравнения узлов обращайтесь к ним напрямую либо повторяйте запрос с закреплением сессии; один экран не агрегирует состояние кластера.