Unit entered failed state — Диагностика и исправление сбоев systemd
Архитектура ошибки и симптомы сбоя
Состояние «Unit service entered failed state (Result: exit-code / signal / timeout / resources)» — базовое уведомление диспетчера systemd о том, что жизненный цикл службы был принудительно прерван. Менеджер systemd классифицирует первопричину сбоя в поле Result:: отказ выполнения команды (exit-code), внешнее принудительное завершение процесса (signal), зависание скриптов запуска/остановки (timeout) или исчерпание системных дескрипторов и памяти (resources).
Диагностическая таблица параметров сбоя
| Параметр | Значение | Инженерный смысл сбоя |
|---|---|---|
| Result: exit-code | Non-zero Exit | Приложение завершилось штатно с ошибкой конфигурации или рантайма. |
| Result: signal | SIGKILL / SIGTERM | Процесс был убит извне (OOM Killer, внешний kill, ядро). |
| Result: timeout | Watchdog / Startup | Превышен лимит TimeoutStartSec или сработал аппаратный Watchdog. |
| Result: resources | ENOMEM / EMFILE | Невозможность аллокации сокетов, памяти, PID или файловых дескрипторов. |
Пошаговое дерево решений и сценарии траблшутинга
Сценарий 1: Проверка точной категории сбоя через systemctl show
# Просмотр точного статуса завершения и кода результата:
systemctl show service_name.service -p Result -p ExecMainStatus -p ExecMainCode
# Проверка общего статуса службы:
sudo systemctl status service_name.serviceСценарий 2: Обработка сбоя Result: signal (поиск убийцы процесса)
Если служба завершилась по сигналу (например, signal=KILL или signal=TERM):
# Проверка, не был ли процесс уничтожен ядром из-за нехватки памяти (OOM Killer):
sudo dmesg -T | grep -i -E "(killed process|oom_reaper|out of memory)"
# Проверка логов auditd на предмет отправки сигналов kill сторонними процессами:
sudo ausearch -sc kill -ts recentСценарий 3: Обработка сбоя Result: resources (увеличение лимитов дескрипторов)
Если службе не хватает файловых дескрипторов (Too many open files):
# Редактирование лимитов службы:
sudo systemctl edit service_name.service
# Добавьте в конфигурацию неограниченные лимиты:
[Service]
LimitNOFILE=655360
LimitNPROC=655360
LimitMEMLOCK=infinity
# Примените настройки:
sudo systemctl daemon-reload
sudo systemctl restart service_name.serviceСценарий 4: Сброс аварийного состояния юнита
# Полная очистка состояния failed для всех юнитов системы:
sudo systemctl reset-failedITSTM настроит комплексный стек мониторинга systemd-экспортера, оптимизирует лимиты cgroups и исключит аварийные падения демонов.
Частые вопросы (FAQ)
Чем Result: signal=KILL отличается от Result: exit-code?
exit-code означает, что приложение само вернуло код ошибки в операционную систему. signal=KILL означает, что само приложение не успело ничего обработать — операционная система или OOM Killer мгновенно уничтожили процесс без вызова деструкторов.
Почему после исправления ошибки служба не запускается по systemctl start?
Если служба превысила лимит попыток перезапуска (StartLimitHit), systemd блокирует дальнейшие запуски. Необходимо предварительно выполнить: sudo systemctl reset-failed <unit>.
Что означает директива LimitNOFILE в unit-файлах?
Директива LimitNOFILE устанавливает максимальное количество одновременно открытых файловых дескрипторов и сокетов (аналог ulimit -n) индивидуально для данного сервиса.
Как автоматически отправлять уведомление в Telegram при переходе сервиса в failed state?
Используйте директиву OnFailure=notify-telegram@%n.service в секции [Unit] и создайте вспомогательный юнит, отправляющий curl-запрос с именем упавшей службы.