mirror of
https://github.com/Vateron-Media/XC_VM.git
synced 2026-10-04 20:03:11 +02:00
The line-by-line web translator reordered words inside `**bold**` spans and misplaced/dropped the markers, producing `**LB` or `****` (empty bold). Mask each `**...**` as ONE atomic sentinel: translate the inner text on its own, then store the whole balanced `**inner**` — the engine never sees the markers and cannot reorder or collapse them. Also harden the anthropic prompt to keep emphasis balanced. Auto-prune: after translating, delete generated docs/ru files whose docs/en source no longer exists (renamed/removed) and drop now-empty dirs, so the tree mirrors docs/en 1:1 (removes the stale development/modules.md and guides/geoip-and-device-detection.md). Bump PROMPT_VERSION to 6 to invalidate the contaminated cache and regenerate docs/ru (0 broken bold spans remaining, aside from pre-existing multi-line bold that spans a soft line break).
126 lines
13 KiB
Markdown
126 lines
13 KiB
Markdown
# Диагностика сервера (`server:diagnose`)
|
|
|
|
Панель помечает прокси-узел/LB-узел **не в сети** исключительно из-за устаревшего сердцебиения (`enabled` + `status = 1` + недавнее `last_check_ago`), которое никогда не сообщает вам, почему узел перестал сообщать. Команда `server:diagnose` отвечает на этот вопрос.
|
|
|
|
```bash
|
|
/home/xc_vm/console.php server:diagnose [server_id]
|
|
```
|
|
|
|
Это команда **доступен только для чтения**: она выполняет только проверки ping/curl/`fsockopen`, `SELECT` запросы и `sudo -n iptables -nL`. Он никогда ничего не перезапускает и не перенастраивает.
|
|
|
|
Реализовано с помощью `src/Cli/Commands/ServerDiagnoseCommand.php`. Команда поставляется в сборках **оба** MAIN и LB — локальный режим - вот и весь смысл ее размещения на узле.
|
|
|
|
---
|
|
|
|
## Два режима
|
|
|
|
Режим автоматически выбирается из того, в котором выполняется команда (`server_id` в `config.ini` → `is_main` в таблице `servers`).:
|
|
|
|
### Режим A — дистанционный датчик от ОСНОВНОГО
|
|
|
|
```bash
|
|
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 — локальная самодиагностика НА узле
|
|
|
|
```bash
|
|
sudo /home/xc_vm/console.php server:diagnose
|
|
```
|
|
|
|
Запустите это **на самом безмолвном узле LB/proxy** — причины обычно находятся там. Аргумент не требуется; узел идентифицирует себя по `config.ini`. Проверки:
|
|
|
|
1. **Мой собственный ряд панелей** — включено/статус/сердцебиение в том виде, в каком их видит основной пользователь.
|
|
2. **Могу ли я добраться до ГЛАВНОГО** — Подключение к базе данных (неявно подтвержденное), ICMP и TCP к широковещательному порту главного сервера.
|
|
3. **Отключил ли я главный брандмауэр?** — сканирует цепочку `iptables INPUT` этого узла на наличие `DROP` IP-адреса главного узла, а также файла-маркера блокировки потока. Это классическая причина "узел отключился без причины": защита от наводнений автоматически отключает общедоступные IP-адреса, и обратные вызовы главного сервера перестают поступать.
|
|
4. **Услуга / nginx** — `systemctl is-active xc_vm` и локальная проверка TCP на собственном широковещательном порту узла.
|
|
5. **Демон-сторожевой пес** — фактический регистратор сердцебиений: демон `watchdog` обновляет `last_check_ago` каждые несколько секунд. Когда его MySQL подключение к главному серверу прерывается, он **ожидает возврата базы данных** (повторяет попытку каждые 5 секунд) и немедленно возобновляет сердцебиение. Вместо этого были запущены более старые сборки, что приводило к **все узлы переходят в автономный режим в один и тот же момент** при любом MySQL перезапуске / сбое в главном меню, пока `cron:servers` не восстановило их.
|
|
6. **Няня крон** — три дополнительных проверки, потому что мертвый watchdog остается мертвым только тогда, когда цепочка няни разорвана:
|
|
- присутствует ли `cron:servers` в **`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` |Была найдена и напечатана одна или несколько вероятных причин|
|
|
|
|
Пример (локальный режим, самоблокирующийся основной):
|
|
|
|
```text
|
|
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` доступ к таблице|
|
|
|
|
Смотрите также: [Инструменты интерфейса командной строки](../guides/cli-tools.md), [Обновление сервера](../administration/server-update.md).
|