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. Проверки:
- **Моя собственная строка панели ** — включено/статус/ сердцебиение в том виде, в каком их видит главный.
- Могу ли я подключиться к ГЛАВНОМУ — подключение к базе данных (неявно подтвержденное), ICMP и TCP к широковещательному порту главного.
- Отключил ли я брандмауэр main? — сканирует цепочку
iptables INPUTэтого узла на наличиеDROPIP-адреса main, а также файла маркера блокировки флуда. Это классическая причина "узел отключился без причины": защита от наводнений автоматически отключает общедоступные IP-адреса, и обратные вызовы главного сервера перестают поступать. - Сервис / nginx —
systemctl is-active xc_vmи локальная проверка TCP на собственном широковещательном порту узла. - ** Сторожевой демон** — фактически записывающий сердцебиение: демон
watchdogобновляетlast_check_agoкаждые несколько секунд. Когда его MySQL подключение к главному серверу прерывается, он ** ожидает восстановления базы данных** (повторяя попытку каждые 5 секунд) и немедленно возобновляет сердцебиение. Вместо этого были запущены более старые сборки, из—за чего ** все узлы отключались в один и тот же момент ** при любом MySQL перезапуске / сбое на главном сервере, покаcron:serversне восстановил их. - Хрон няни — три дополнительные проверки, потому что мертвый watchdog остается мертвым только тогда, когда цепочка няни разорвана:
- присутствует ли
cron:serversв crontab пользователя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 на главном сервере) |
| Все узлы падают в один и тот же момент | Перезапуск 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 доступ к таблице |
Смотрите также: Инструменты интерфейса командной строки, Обновление сервера.