Диагностика сервера (server:diagnose)¶
Панель помечает прокси-узел/LB-узел не в сети исключительно из-за устаревшего сердцебиения (enabled + status = 1 + недавнее last_check_ago), которое никогда не сообщает вам, почему узел перестал сообщать. Команда server:diagnose отвечает на этот вопрос.
Это команда доступен только для чтения: она выполняет только проверки ping/curl/fsockopen, SELECT запросы и sudo -n iptables -nL. Он никогда ничего не перезапускает и не перенастраивает.
Реализовано с помощью src/Cli/Commands/ServerDiagnoseCommand.php. Команда поставляется в сборках оба MAIN и LB — локальный режим - вот и весь смысл ее размещения на узле.
Два режима¶
Режим автоматически выбирается из того, в котором выполняется команда (server_id в config.ini → is_main в таблице servers).:
Режим A — дистанционный датчик от ОСНОВНОГО¶
Проверяет целевой узел снаружи и считывает его состояние на панели управления:
| Проверять | О чем это вам говорит |
|---|---|
| Включено / Статус / Сердцебиение | Как панель в данный момент видит узел (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 — локальная самодиагностика НА узле¶
Запустите это на самом безмолвном узле LB/proxy — причины обычно находятся там. Аргумент не требуется; узел идентифицирует себя по config.ini. Проверки:
- Мой собственный ряд панелей — включено/статус/сердцебиение в том виде, в каком их видит основной пользователь.
- Могу ли я добраться до ГЛАВНОГО — Подключение к базе данных (неявно подтвержденное), ICMP и TCP к широковещательному порту главного сервера.
- Отключил ли я главный брандмауэр? — сканирует цепочку
iptables INPUTэтого узла на наличиеDROPIP-адреса главного узла, а также файла-маркера блокировки потока. Это классическая причина "узел отключился без причины": защита от наводнений автоматически отключает общедоступные IP-адреса, и обратные вызовы главного сервера перестают поступать. - Услуга / nginx —
systemctl is-active xc_vmи локальная проверка TCP на собственном широковещательном порту узла. - Демон-сторожевой пес — фактический регистратор сердцебиений: демон
watchdogобновляетlast_check_agoкаждые несколько секунд. Когда его MySQL подключение к главному серверу прерывается, он ожидает возврата базы данных (повторяет попытку каждые 5 секунд) и немедленно возобновляет сердцебиение. Вместо этого были запущены более старые сборки, что приводило к все узлы переходят в автономный режим в один и тот же момент при любом MySQL перезапуске / сбое в главном меню, покаcron:serversне восстановило их. - Няня крон — три дополнительных проверки, потому что мертвый watchdog остается мертвым только тогда, когда цепочка няни разорвана:
- присутствует ли
cron:serversвxc_vmкронтаб пользователя (если отсутствует, восстановите с помощьюrm -f /home/xc_vm/tmp/crontabи перезапустите службу); - активна ли система служба cron (нет cron → crontab никогда не запускается);
- является предыдущим
cron:serversэкземпляром висел на своем замке cron — зависший экземпляр блокирует каждый последующий запуск на срок до 30 минут (acquireCronLockистекший тайм-аут), что в точности соответствует тому, как один сбой в работе базы данных удерживает узел в автономном режиме в течение получаса. Команда выводит удерживающий PID и команду завершения. - Перекос часов —
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 на главном сервере) |
| All nodes drop at the same moment | Перезапуск 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 доступ к таблице |
Смотрите также: Инструменты интерфейса командной строки, Обновление сервера.