В systemd большинство «мистических» падений сводится к двум вещам: что именно сказал сервис в логах и какие ограничения по времени или частоте запусков наложил менеджер. Типичные симптомы знакомы: service failed to start, бесконечный restart loop, «вчера работало — сегодня нет», а на systemctl restart — мгновенное failed.
Ниже — практичный разбор, как быстро собрать картину по systemctl status и journalctl, и как корректно настроить TimeoutStartSec, TimeoutStopSec, StartLimitBurst, StartLimitIntervalSec, чтобы не маскировать проблему, а устранять её.
Чек-лист диагностики: что делать, когда service failed to start
Когда сервис не стартует, важно не «тыкать» в конфиги вслепую. Начните с минимального набора команд (как шаблон):
systemctl status myservice.service
journalctl -u myservice.service -b --no-pager
systemctl show myservice.service -p ExecStart -p MainPID -p ActiveState -p Result -p TimeoutStartUSec -p TimeoutStopUSec -p Restart -p StartLimitIntervalUSec -p StartLimitBurst
Первая команда даёт сжатый статус и последние строки логов. Вторая — нормальную историю сообщений из journald за текущую загрузку (-b). Третья — «истинные» значения параметров с учётом drop-in и дефолтов systemd.
systemctl status: где искать причину
systemctl status удобно читать по блокам:
- Loaded: откуда взят unit-файл, есть ли drop-in (Overrides). Если видите
drop-in— значит на сервис влияют дополнительные настройки, и их нужно учитывать. - Active: состояние и причина. Например,
failed (Result: timeout)часто указывает на истечениеTimeoutStartSecилиTimeoutStopSec. - Process: какие команды выполнялись (pre/start/post), их PID и коды возврата.
- Logs: несколько последних строк — полезно, но почти всегда недостаточно, поэтому дальше идём в
journalctl.
Частая ловушка: статус показывает только «общее» (например, timeout), а реальная причина — внутри приложения (долгая миграция БД, зависание DNS, недоступный диск, ожидание порта, блокировки и т. п.).
Если у вас сервисы живут на отдельной машине, проще отлавливать такие истории на изолированном окружении: отдельный VDS под приложение и зависимости часто экономит время на диагностике и снижает «побочные эффекты» от рестартов на соседние сайты.
journalctl: как читать логи так, чтобы быстро найти нужное
Логи конкретного сервиса за текущую загрузку
Базовая команда для юнитов:
journalctl -u myservice.service -b --no-pager
Если сервис много пишет, ограничьте вывод по времени:
journalctl -u myservice.service -S "2026-03-05 10:00:00" --no-pager

Только ошибки и предупреждения
Удобно при шумных логах:
journalctl -u myservice.service -b -p warning --no-pager
Следить за логами в момент перезапуска
Один терминал «смотрит», второй — перезапускает:
journalctl -u myservice.service -f
systemctl restart myservice.service
Понять, это timeout systemd или падение процесса
Если это именно таймаут запуска, в журнале часто встречаются формулировки уровня systemd вроде «start operation timed out». Если процесс падает сам — будут сообщения приложения или exit code. Важно различать:
- Timeout: systemd «ждал слишком долго» (истёк таймаут).
- Exit-code: приложение завершилось с ошибкой.
- Start-limit-hit: systemd перестал пытаться стартовать из-за слишком частых неудач.
Если в логах не хватает контекста о запуске воркеров и фоновых процессов, полезно сравнить подходы: как запускать очереди и воркеры через systemd.
Почему возникает restart loop и что такое StartLimit*
Механика простая: у вас включён Restart=on-failure (или он задан пакетом), сервис падает, systemd пытается поднять его снова, и так по кругу. Чтобы сервер не оказался в вечном «мелькании» процессов и логов, у systemd есть ограничители: StartLimitBurst и StartLimitIntervalSec.
Идея: за интервал времени (StartLimitIntervalSec) разрешено не более StartLimitBurst попыток запуска. Превысили — получите start-limit-hit, и systemd перестанет автоматически перезапускать сервис.
StartLimit* не лечит сервис — он защищает систему. Если просто «увеличить лимиты», можно замаскировать проблему и получить бесконечный restart loop, забивающий журнал и CPU.
Как посмотреть, что именно сработало
systemctl status myservice.service
systemctl show myservice.service -p NRestarts -p Restart -p StartLimitIntervalUSec -p StartLimitBurst -p Result
NRestarts помогает понять масштаб: сервис умирает раз в сутки или 200 раз за минуту.
Как временно «разблокировать» start-limit-hit
Если вы поправили конфиг и хотите, чтобы systemd снова пробовал стартовать:
systemctl reset-failed myservice.service
systemctl start myservice.service
TimeoutStartSec: когда systemd убивает «долго стартующий» сервис
TimeoutStartSec — время, за которое сервис должен перейти в состояние «запущен» с точки зрения systemd. Если не успел — systemd считает запуск проваленным и действует по настройкам перезапуска и типу юнита.
Важно: «запущен» в понимании systemd — это не «приложение готово обслуживать трафик», а выполнение условий конкретного типа (Type=): завершение стартовой команды и, иногда, получение уведомления готовности.
Типы сервисов и их влияние на таймауты
Type=simple: systemd считает сервис запущенным сразу после запуска процессаExecStart. Таймаут проявится, если стартовый процесс «висит» (например, оболочка ждёт подкоманду) или вы запускаете что-то, что не переходит в стабильное состояние.Type=forking: сервис должен «форкнуться» и завершить родительский процесс. Если daemon не форкается или не появляется PIDFile — легко упереться вTimeoutStartSec.Type=notify: сервис должен отправить systemd сигнал готовности. Если приложение реально поднялось, но notify не отправлен или не настроен, systemd будет ждать и в итоге сработает timeout.Type=oneshot: запуск — это выполнение команды. Если команда долгая, таймаут становится критичным.
Как понять, что именно упирается в TimeoutStartSec
Сначала проверьте фактические значения таймаутов:
systemctl show myservice.service -p TimeoutStartUSec -p TimeoutStopUSec
Дальше найдите в журнале момент запуска и что происходило до убийства. Часто видно, что сервис завис на сетевой операции, миграции, ожидании блокировки или прогреве кэша.
Увеличивать TimeoutStartSec или чинить причину?
Увеличивать TimeoutStartSec оправдано, когда:
- есть легитимная долгая стадия старта (миграции, прогрев, проверка данных);
- вы понимаете верхнюю границу времени и готовы её контролировать;
- есть логирование прогресса, чтобы отличать «долго работает» от «завис».
Если сервис иногда «залипает» на неопределённое время, увеличение таймаута только растянет простои и усложнит диагностику.
TimeoutStopSec: почему сервис «не останавливается» и чем это опасно
TimeoutStopSec — время, за которое сервис обязан остановиться после запроса stop. Если не успевает — systemd применит принудительное завершение (в зависимости от настроек KillSignal, SendSIGKILL и поведения процесса).
Практические кейсы, когда TimeoutStopSec важен:
- демоны с долгим завершением (сброс буферов, закрытие соединений, flush на диск);
- воркеры очередей, которым нужно корректно «доделать» задачи;
- сервисы, где важно освобождение lock-файлов, сокетов и корректная остановка слушателей.
Слишком маленький
TimeoutStopSecможет приводить к «грязным» остановкам и повреждению данных. Слишком большой — к долгим ребутам и зависанию деплоя, если процесс уже не отвечает.

Как менять StartLimit* и Timeout* правильно: drop-in override
Не редактируйте unit-файл пакета напрямую: обновление всё перезапишет. Делайте override (drop-in). Самый удобный путь — открыть редактор через systemd:
systemctl edit myservice.service
Откроется файл вида /etc/systemd/system/myservice.service.d/override.conf. Пример настроек (шаблон — подставляйте свои значения осознанно):
[Service]
TimeoutStartSec=120
TimeoutStopSec=60
Restart=on-failure
RestartSec=5
[Unit]
StartLimitIntervalSec=300
StartLimitBurst=5
Дальше примените изменения:
systemctl daemon-reload
systemctl restart myservice.service
systemctl status myservice.service
Почему часть параметров в [Unit], а часть в [Service]
TimeoutStartSec и TimeoutStopSec относятся к поведению сервиса, поэтому секция [Service]. А StartLimitIntervalSec и StartLimitBurst — логика ограничения попыток запуска юнита, поэтому секция [Unit]. Держаться «канонической» раскладки проще для поддержки, особенно если сервисом будут заниматься разные админы.
Типовые сценарии и решения
Сервис стартует долго из-за миграций: TimeoutStartSec нужен больше
Если в journalctl видно, что процесс реально работает (идёт миграция) и стабильно укладывается, например, в 70–80 секунд — установите TimeoutStartSec с запасом (120–180 секунд) и обязательно логируйте прогресс.
Сервис мгновенно падает и попадает в restart loop: сначала остановите шторм
Когда сервис падает за доли секунды, автоматический рестарт превращает логи в кашу. Временно выключите рестарты (или увеличьте RestartSec) и спокойно разберите причину:
systemctl edit myservice.service
[Service]
Restart=no
systemctl daemon-reload
systemctl restart myservice.service
После исправления верните Restart=on-failure и подберите StartLimit* так, чтобы сервис не «молотил» систему при фатальной ошибке конфигурации.
StartLimit* срабатывает «слишком быстро»: сервису нужно время на прогрев
Иногда сервису нужны несколько попыток (например, он ждёт БД, которая поднимается позже). Тогда:
- увеличьте
StartLimitIntervalSec, чтобы окно было шире; - подберите
StartLimitBurstтак, чтобы хватало попыток на «ожидание зависимостей»; - добавьте разумный
RestartSec, чтобы попытки не шли подряд без пауз.
Но лучшее решение — корректные зависимости и ожидание готовности (через правильный After=/Wants=, а также через механизмы самого приложения), а не бесконечные рестарты.
Если проблема всплывает из-за «смешанных» окружений (несовместимые версии библиотек, разные сайты на одной машине, конкуренция за ресурсы), иногда проще развести сервисы по тарифам: виртуальный хостинг для сайтов и отдельная машина под тяжёлые демоны или очереди.
Мини-рутина для инцидента: 10 минут до понятной причины
- Снимите статус:
systemctl status myservice.service. - Посмотрите логи юнита за текущую загрузку:
journalctl -u myservice.service -b. - Уточните, timeout это или exit-code: поле
Resultи формулировки в журнале. - Проверьте текущие таймауты и лимиты через
systemctl show(не «на глаз»). - Если это restart loop — временно уменьшите шум (выключите рестарт или увеличьте
RestartSec), чтобы диагностировать спокойно. - Исправьте первопричину (конфиг, права, сеть, зависимости, доступность сокетов, портов, диска).
- Только затем подстройте
TimeoutStartSec/TimeoutStopSecиStartLimit*под реальное поведение сервиса.
Коротко: что запомнить
systemctl status— быстрый ориентир, но ключевые детали почти всегда вjournalctl.TimeoutStartSecиTimeoutStopSecуправляют тем, сколько systemd готов ждать старт и остановку; неверные значения дают «ложные» падения или долгие зависания.StartLimitBurstиStartLimitIntervalSecзащищают систему от штормовых перезапусков и помогают остановить restart loop.- Меняйте параметры через drop-in (
systemctl edit), затемsystemctl daemon-reload.
Если довести до привычки связку «systemctl status → journalctl -u → systemctl show», большинство проблем «service failed to start» превращаются в понятный, повторяемый разбор вместо гадания.


