Files
XC_VM/docs/ru/administration/server-diagnostics.md
T
2026-08-21 21:56:31 +03:00

13 KiB

Диагностика сервера (server:diagnose)

Панель помечает узел proxy/LB как "отключенный" исключительно из-за устаревшего сердцебиения (enabled + status = 1 + недавнее last_check_ago), которое никогда не сообщает вам, почему узел перестал сообщать. Команда server:diagnose отвечает на этот вопрос.

/home/xc_vm/console.php server:diagnose [server_id]

Команда доступна только для чтения: она выполняет только проверки ping/curl/fsockopen, SELECT и sudo -n iptables -nL. Она никогда ничего не перезапускает и не перенастраивает.

Реализовано с помощью src/Cli/Commands/ServerDiagnoseCommand.php. Команда поставляется как в основной, так и в LB сборках — весь смысл ее использования на узле заключается в локальном режиме.


Два режима

Режим автоматически выбирается из того, в котором выполняется команда (server_id в config.ini → is_main в таблице servers).:

Режим A — дистанционный датчик от ОСНОВНОГО

sudo /home/xc_vm/console.php server:diagnose <server_id>

Проверяет целевой узел снаружи и считывает его состояние на панели управления:

Проверять О чем это вам говорит
Включено / Статус / Сердцебиение Как панель в данный момент видит узел (status = 4 означает сбой установки/подготовки)
Пинг по протоколу ICMP Жив ли вообще носитель
TCP к http_broadcast_port Доступен ли nginx, или порт удален
HTTP GET /api Действительно ли PHP отвечает за nginx
Смещение часов time_offset против панели (перекос > 30 с может привести к переключению узла в режим онлайн/оффлайн)
Очередь сигналов Неиспользованные строки в signals для этого узла (задержка > 120 секунд = цикл обратного вызова узла застрял)

Комбинации датчиков соответствуют причинам:

  • Порт ICMP + не закрыт — узел выключен, разделен сетью или полностью защищен брандмауэром.
  • ICMP replies but the port is dropped — the classic: the node's own iptables blocked the main's IP (RootSignals flood/block false-positive), or nginx/the service is down. Run the local mode on the node for the exact cause.
  • Порт открыт, но /api молчит — nginx включен, PHP нет: проверьте php-fpm на узле.
  • **/api отвечает, но частота сердцебиения устарела ** — демон узла watchdog (программа записи сердцебиений) не запущен или не может выполнить запись в базу данных панели. Запустите локальный режим на узле.

Режим B — локальная самодиагностика НА узле

sudo /home/xc_vm/console.php server:diagnose

Запустите это ** на самом узле LB/proxy с отключенным доступом ** — причины обычно находятся там. Аргумент не требуется; узел идентифицирует себя с помощью config.ini. Проверки:

  1. **Моя собственная строка панели ** — включено/статус/ сердцебиение в том виде, в каком их видит главный.
  2. Могу ли я подключиться к ГЛАВНОМУ — подключение к базе данных (неявно подтвержденное), ICMP и TCP к широковещательному порту главного.
  3. Отключил ли я брандмауэр main? — сканирует цепочку iptables INPUT этого узла на наличие DROP IP-адреса main, а также файла маркера блокировки флуда. Это классическая причина "узел отключился без причины": защита от наводнений автоматически отключает общедоступные IP-адреса, и обратные вызовы главного сервера перестают поступать.
  4. Сервис / nginx — systemctl is-active xc_vm и локальная проверка TCP на собственном широковещательном порту узла.
  5. ** Сторожевой демон** — фактически записывающий сердцебиение: демон watchdog обновляет last_check_ago каждые несколько секунд. Когда его MySQL подключение к главному серверу прерывается, он ** ожидает восстановления базы данных** (повторяя попытку каждые 5 секунд) и немедленно возобновляет сердцебиение. Вместо этого были запущены более старые сборки, из—за чего ** все узлы отключались в один и тот же момент ** при любом MySQL перезапуске / сбое на главном сервере, пока cron:servers не восстановил их.
  6. Хрон няни — три дополнительные проверки, потому что мертвый watchdog остается мертвым только тогда, когда цепочка няни разорвана:
    • присутствует ли cron:servers в crontab пользователя xc_vm (если отсутствует, создайте заново с помощью rm -f /home/xc_vm/tmp/crontab и перезапустите службу);
    • активна ли системная служба cron (нет cron → crontab никогда не запускается);
    • является ли предыдущий экземпляр cron:servers ** зависшим из—за блокировки cron ** - зависший экземпляр блокирует каждый последующий запуск на срок до 30 минут (acquireCronLock истекший тайм-аут), что в точности соответствует тому, как один сбой в работе базы данных удерживает узел в автономном режиме в течение получаса. Команда выводит удерживающий PID и команду завершения.
  7. Перекос часов — time_offset относительно панели.

Примечание: для проверки iptables требуется sudo без пароля (sudo -n). Без него проверка выдает сообщение о cannot check (need sudo iptables) вместо сбоя — запустите команду как root для получения полной картины.


Коды вывода и выхода

При каждой проверке выводится одна выровненная строка [OK]/[WARN], за которой следует пронумерованная сводка о возможных причинах с указанием точной команды устранения, если таковая существует (например, строка разблокировки iptables -D INPUT ... -j DROP).

Код выхода Значение
0 Очевидная причина не обнаружена (или цель сама по себе является ОСНОВНОЙ — диагностировать нечего).
1 Ошибка использования: отсутствует/неизвестно server_id
2 Была найдена и напечатана одна или несколько вероятных причин

Пример (локальный режим, самоблокирующийся основной):

Self-diagnosis on node #3 — LB-Frankfurt (type 1)
----------------------------------------------------------------
[OK]   Enabled          yes
[OK]   Status           1 (online)
[WARN] Heartbeat        last check-in 641s ago (limit 180s)
[OK]   DB → main        reachable (this query ran)
[OK]   Ping main        reply (203.0.113.10)
[WARN] Main :8080       closed/timeout
[WARN] Main in iptables DROP present (+flood marker)
[OK]   Service xc_vm    active
[OK]   nginx :8080      listening
[OK]   watchdog daemon  running
[OK]   cron:servers     in xc_vm crontab
[OK]   Clock offset     2s vs panel
----------------------------------------------------------------
Probable cause(s):
  1. Heartbeat is stale (641s > 180s): the node stopped reporting — the checks below narrow down why.
  2. This node has DROPPED the main's IP 203.0.113.10 in its own iptables (flood/block false-positive). Unblock: `sudo iptables -D INPUT -s 203.0.113.10 -j DROP && sudo rm -f /home/xc_vm/tmp/flood/block_203.0.113.10`.

Краткий справочник — Распространенные причины

Симптом Вероятная причина Чинить
Звенит, порт сброшен iptables узла заблокировал основной IP-адрес sudo iptables -D INPUT -s <main_ip> -j DROP + удалить маркер block_<ip> (команда выводит точную строку)
Ни пинга, ни порта Отключен хост / сетевой раздел / внешний брандмауэр Проверьте консоль хостинга, маршруты, брандмауэр провайдера
Порт открыт, /api отключен сбой php-fpm Перезапустите службу xc_vm на узле
/api отлично, сердцебиение замедлилось Сторожевой демон мертв (завершает работу при потере соединения с базой данных) sudo -u xc_vm console.php watchdog на узле; проверьте разрешения базы данных (tools mysql на главном сервере)
Все узлы падают в один и тот же момент Перезапуск MySQL /сбой на главном сервере приводит к одновременному сбою watchdog на каждом узле (фатально для сборок до исправления; текущие сборки переждут это). Проверьте журнал ошибок main MySQL во время сброса; обновите узлы, чтобы watchdog пережил перебои в работе
Закрылки узлов онлайн/оффлайн Перекос часов > 30 с (или повторяющиеся сигналы MySQL) Синхронизируйте протокол NTP на узле; проверьте стабильность MySQL на главном
Статус = 4 Произошла ошибка установки/обеспечения Повторный запуск server:install из основного

Связанные файлы

Файл Роль
src/Cli/Commands/ServerDiagnoseCommand.php Диагностическая команда (в обоих режимах)
src/Cli/Commands/WatchdogCommand.php Демон watchdog — записывает сердцебиение (last_check_ago)
src/Cli/CronJobs/ServersCronJob.php Хрон няни — перезапускает мертвого watchdog
src/Cli/CronJobs/RootSignalsCronJob.php Применяет блокировки iptables (источник ложных срабатываний)
src/Domain/Server/ServerRepository.php servers доступ к таблице

Смотрите также: Инструменты интерфейса командной строки, Обновление сервера.