Files
XC_VM/docs/ru/administration/server-diagnostics.md
T
Divarion_D bdbcde97c7 docs: commit generated ru, translate locally before release (not in CI)
CI translation was slow, so move it out of GitHub Actions: docs/ru is now a
committed, generated tree refreshed LOCALLY before a release; CI only builds it.

- pages.yml: drop the setup-python/cache/translate steps — the workflow now just
  installs the build toolchain and runs `mkdocs build --strict` on the committed
  en+ru trees.
- .gitignore: stop ignoring docs/ru (now committed); keep site/ + .docs-cache/.
- Split deps: docs/requirements.txt = build only (mkdocs-material, static-i18n,
  used by CI); tools/docs/requirements.txt = translators (local-only).
- Makefile: docs-venv installs both; docs-build/docs-serve no longer translate
  (translation is the deliberate `make docs-translate` release step).
- updates_checklist.md: new "Regenerate translated documentation" step
  (make docs-translate + docs-build, commit docs/ru with the release commit).
- Commit the generated docs/ru (37 files, translators/yandex).

Rule: edit ONLY docs/en; docs/ru is generated — never hand-edit it.
2026-08-20 22:37:44 +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 Действительно ли @@ 1@@ отвечает за @@ 0@@
Смещение часов time_offset против панели (перекос > 30 с может привести к переключению узла в режим онлайн/оффлайн)
Очередь сигналов Неиспользованные строки в signals для этого узла (задержка > 120 секунд = цикл обратного вызова узла застрял)

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

  • Порт ICMP + не закрыт — узел выключен, разделен сетью или полностью защищен брандмауэром.
  • **ICMP отвечает, но порт не указан ** — классический случай: собственные iptables узла заблокировали IP-адрес главного сервера (RootSignals выдает ложные срабатывания), или nginx/служба не работает. Запустите локальный режим на узле для выяснения точной причины.
  • Порт открыт, но /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 соединение с main прерывается, он ** ожидает возврата к базе данных ** (повторяя попытку каждые 5 секунд) и немедленно возобновляет сердцебиение. Вместо этого были запущены более старые сборки, из—за чего ** все узлы отключались в один и тот же момент ** при любом MySQL перезапуске / сбое на главном сервере, пока cron:servers не восстановил их.
  6. Хрон няни — три дополнительные проверки, потому что мертвый watchdog остается мертвым только тогда, когда цепочка няни разорвана:
    • присутствует ли cron:servers в xc_vm пользовательской crontab (если отсутствует, создайте заново с помощью 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 доступ к таблице

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