Supervisord: почему процессы падают и не поднимаются
Картина, с которой сталкиваются чаще всего: обработчик очереди запущен в сессии терминала, ночью сессия рвётся, процесс получает SIGHUP и умирает. Никто этого не заметил — к утру в очереди накапливаются тысячи необработанных заявок, а дежурный поднимает сервис вручную и дочищает хвост.
Причина в том, что упавший сервис не поднимается сам: ядро лишь завершает процесс и отдаёт код возврата родителю. Если родителем была оболочка или временный скрипт, забирать возврат некому — процесс остаётся сиротой, и повторный старт никто не инициирует. Тот же механизм порождает процессы-зомби: родитель не забирает статус, запись остаётся в таблице процессов и копится, пока новые потомки уже не создать.
Supervisord закрывает это на уровне операционной системы: демон стартует как системная служба, сам выступает родителем для каждой программы и потому забирает код возврата — зомби не накапливаются. Автозапуск процессов на сервере описывается декларативно: в конфигурации для программы задаются команда, рабочий каталог, пользователь, признак автозапуска, автоперезапуск, пауза между попытками и их предельное число.
Журналы работы процессов не теряются: поток вывода и ошибок пишется в отдельные файлы с ротацией по размеру и числу копий, поэтому разбор ночного сбоя не требует искать следы по всей машине. Состояние видно одной командой, а ручной перезапуск приложения выполняется точечно, не задевая соседние сервисы. Ниже разбираем, как это закрывается на практике.
Что меняется после внедрения контроля процессов
До внедрения контроля процессов львиная доля простоев приходилась на падение процесса, которое никто не заметил: служба умирала ночью, а узнавали об этом из обращений утром. Время восстановления сервиса складывалось из времени обнаружения плюс ручной запуск — десятки минут и обязательное участие дежурного.
Supervisord переводит это в управляемый режим. Процессы описываются декларативно: автоматический перезапуск срабатывает по аварийному коду возврата, startretries и startsecs отсекают «мигающие» службы, exitcodes задаёт список штатных завершений — плановая остановка не маскируется под сбой и не вызывает цикл рестартов.
Наблюдаемость состояния служб строится на выводе supervisorctl status и обработчике событий: переход в аварийное состояние уходит алертом в мониторинг вместе с хвостом лога процесса. Дежурная смена видит не «сервер недоступен», а конкретную службу, причину и число попыток — диагностика начинается с факта, а не с поиска.
Итог измерим: восстановление укладывается в секунды и не требует человека, доля простоев из-за незамеченных падений падает до единиц процентов, число ручных вмешательств сокращается в разы. Нагрузка на дежурную смену перестаёт расти вместе с числом сервисов.
Supervisord и альтернативы: что выбрать для сервиса
Выбор способа запуска редко упирается в функциональность: почти любой менеджер процессов умеет перезапустить упавший сервис и писать лог. Разница проявляется в деталях — кто следит за процессом, как описываются зависимости запуска, что происходит после перезагрузки узла и как менять конфигурацию без простоя.
Ниже — варианты, между которыми реально выбирают на проектах. Комбинировать их можно: внутри контейнера часто остаётся свой супервизор для нескольких процессов приложения.
| Вариант | Когда подходит | Ограничения |
|---|---|---|
| Supervisord как менеджер процессов | Несколько сервисов на одной машине: группы, приоритеты запуска, единый статус | Не является PID 1 — нужен внешний автозапуск, не управляет службами уровня ОС |
| Системный менеджер служб | Один-два сервиса, автозапуск при загрузке, лимиты ресурсов и журнал | Зависимости только через цели, гибких групп процессов нет |
| Приложение как PID 1 в контейнере | Микросервис с одним процессом и декларативной конфигурацией | Не перезапускает дочерние процессы; для нескольких нужен супервизор |
| Оркестратор | Много реплик, самовосстановление, поочерёдные обновления без простоя | Избыточен для одной машины, требует манифестов и отдельной инфраструктуры |
Практическое правило: один процесс в контейнере — минимум внешнего управления; несколько процессов на узле — Supervisord с приоритетами и группами; системные службы — профильному системному менеджеру. Зависимости запуска прописываем явно: иначе после перезагрузки сервис поднимается раньше, чем готовы его база и кэш, и падает в цикле рестартов.
Этапы внедрения: от аудита до передачи в эксплуатацию
Инвентаризация — половина работы. Прежде чем писать конфигурацию, наши инженеры собирают всё, что фактически запускается на серверах: сервисы, поднятые вручную в чужой сессии, задачи планировщика, скрипты, оставшиеся от прошлых подрядчиков, «временные» решения, которые живут годами. Supervisord берёт их под управление — но только если точно известно, что он должен держать и в каком порядке.
Порядок работ
- Аудит запуска сервисов. Фиксируем, что работает сейчас, кто владелец процесса, куда пишутся логи, что перезапускается при сбое, а что умирает молча.
- Схема зависимостей процессов. Определяем, кто кого ждёт: приложение не стартует раньше базы, фоновые задачи — раньше очереди. На схеме видно порядок подъёма и порядок остановки.
- Настройка управления. Переносим сервисы под Supervisord: автозапуск, правила перезапуска, лимиты, ротация логов, раздельные системные пользователи.
- Проверка сценариев отказа. Убиваем процессы, роняем зависимости, перезагружаем машину — смотрим, поднимается ли всё в нужном порядке и не остаётся ли «полуживых» состояний.
- Приёмочные проверки. Прогоняем согласованный список проверок на тестовом и боевом контурах вместе с вашей командой; расхождения устраняем до передачи.
- Передача в эксплуатацию. Отдаём конфигурации, схему, инструкции по типовым операциям и регламент действий при сбое.
Такой порядок снимает главный риск — систему, которая работает «пока её никто не трогал». После передачи ваша команда управляет сервисами штатными командами, а не поиском того, кто помнит, как это запускалось.
Конфигурации, политики перезапуска и регламенты
Комплект документации передаём не «для галочки»: по нему дежурный инженер, который не участвовал во внедрении, сможет поднять упавший сервис и понять, почему тот остановился. Ниже — что физически остаётся у заказчика в репозитории конфигураций и во внутренней базе знаний.
-
Файлы конфигурации процессов — по одному описанию на сервис в отдельном каталоге, с путями, переменными окружения, лимитами попыток и порядком запуска; конфигурации версионируются, изменения проходят проверку.
-
Политика перезапуска — какие коды завершения считаются нормой, сколько попыток даётся на восстановление, что делать при повторном падении: оставить остановленным, поднять с задержкой или эскалировать.
-
Права доступа к процессам — от какого пользователя работает каждый сервис, кто вправе останавливать и перезапускать его через управляющий интерфейс, как ограничен доступ к логам и сокету.
-
Схема групп и зависимостей — что поднимается первым, какой процесс ждёт соседний, какой нельзя останавливать в одиночку без риска для остальных.
-
Регламент дежурной смены — таблица «симптом → действие», порог, при котором дежурный зовёт инженера, шаблон эскалации и порядок фиксации инцидента.
-
Инструкция по сопровождению — как добавить новый процесс, как плавно вывести сервис из ротации, где смотреть логи и как откатить конфигурацию к предыдущей ревизии.
-
Сбор метрик и оповещения — состояние процессов, рост потребления памяти и частые перезапуски видны до того, как сервис упадёт окончательно, а не по утреннему звонку.
Каждый пункт проходит приёмку на тестовом контуре: мы намеренно роняем процессы и смотрим, отрабатывает ли политика так, как записана в регламенте.
Кейс: сервис перестал падать незаметно для команды
До внедрения
Сервис держался на пяти процессах — воркеры очереди, планировщик задач, обработчик внешних событий — и запускался вручную из консоли. Когда воркер падал, очередь продолжала расти, а команда узнавала об этом по жалобе клиента: от отказа до первого сигнала проходило около трёх часов, ещё столько же — на разбор и ручной перезапуск. За месяц фиксировали 11 таких остановок, из них 8 обнаруживали пользователи, а не мониторинг.
Что изменили и что стало
Каждый процесс описали декларативно: команда запуска, зависимости, рабочая директория, поведение при остановке и лимиты перезапусков. Supervisor взял на себя контроль состояния, автозапуск после перезагрузки узла и автоматическое восстановление упавших процессов — с задержкой и потолком попыток, чтобы цикл падений не маскировался под стабильную работу. Потоки вывода свели в один лог с ротацией, а на события восстановления и превышения лимита повесили оповещения дежурному.
Доля остановок, которые закрываются без человека, выросла с нуля до 92% — восстановление занимает секунды вместо часов. Время реакции на реальную аварию сократилось с трёх часов до нескольких минут: сигнал теперь приходит от системы, а не от клиента. Ручных вмешательств осталось 1-2 в месяц вместо 11, и связаны они с дефектами в коде, а не с инфраструктурой. Отчёт по результатам включил карту процессов, конфигурацию, схему оповещений и регламент дежурного — состояние сервиса понятно без чтения исходников.
Чем Supervisord отличается от штатного менеджера служб
Штатный менеджер служб (в большинстве дистрибутивов — systemd) рассчитан на хостовый уровень: один юнит — одна служба, зависимости между юнитами, автозапуск при загрузке, лимиты через cgroups и общий бинарный журнал. Для системных демонов это именно то, что нужно — он поднимается раньше прикладного кода и переживает перезагрузку вместе с хостом.
Supervisord закрывает другой слой — группу прикладных процессов внутри одного окружения и без прав суперпользователя. Конфигурация плоская: INI-секции [program:имя] с числом экземпляров, шаблоном имени процесса, переменными окружения, политикой повторов, кодом выхода для штатной остановки и приоритетом, который задаёт порядок старта; [group:...] собирает десяток процессов в одну управляемую единицу.
Гибкость настройки запуска — ключевое отличие. Штатный менеджер ждёт, что приложение не форкается и корректно ведёт себя с сокетом; Supervisord работает и с теми, кто демонизируется, ждёт соседа по порту или падает на прогреве — задаёшь задержку перед повтором, предел попыток, сигнал остановки. Управление группой идёт через supervisorctl: перезапуск всех процессов одной командой, статус по каждому экземпляру и единый журнал событий — отдельный файл на процесс либо общий поток через обработчик событий.
Где штатный надёжнее: автозапуск после перезагрузки, изоляция и лимиты, реакция на падение по cgroup, а не по устаревшему pid-файлу. Поэтому подходы не спорят, а совмещаются: Supervisord живёт под штатной службой и внутри держит группу приложений — хост получает предсказуемый старт, приложение — гибкие правила повторов и порядок запуска.
Технические сомнения и типичные ошибки настройки
После перезагрузки сервер возвращает не «то же состояние», а то, что описано в конфигурации: автозапуск включается флагом autostart, порядок задаёт priority — база данных поднимается раньше приложения, которое к ней подключается. Если процесс Supervisord запускали вручную из сессии, после перезапуска его не будет: нужен unit в systemd или init-скрипт, иначе конфиги на месте, а процессов нет.
Новую программу добавляют на ходу: reread перечитывает файлы, update поднимает только новые и изменённые группы, остальные процессы не перезапускаются. Конфиг при этом держат в отдельном файле подключённой директории — тогда правка одного сервиса не задевает соседние.
Что произойдёт после перезагрузки сервера?
Поднимутся только программы с autostart=true, а сам демон — через unit systemd с автозапуском. Ручной старт из терминала не сохраняется.
Можно ли подключить сервис без простоя остальных?
Да, reread и update затрагивают лишь изменённые группы. При синтаксической ошибке в файле демон откажет целиком и оставит прежнюю версию работать.
Как ведёт себя система при нехватке памяти?
Жертву выбирает OOM-killer по значению oom_score_adj. Демон поднимает упавший процесс снова, и без ограничения startretries получается цикл перезапусков, который добивает соседей.
Что делать, если приложение порождает дочерние процессы?
Одного сигнала главному процессу мало: нужны stopasgroup и killasgroup, иначе воркеры остаются висеть и держат порт или блокировку в базе.
Какие ошибки встречаются чаще всего?
Завышенный startsecs скрывает падения на старте, отсутствие environment даёт сервис без нужных переменных, логи без ротации забивают диск. Отдельный пункт — запуск от root: демон это позволяет, пока не потребуется изоляция прав.
Обсудим вашу задачу: что прислать для оценки
Чтобы вернуться со схемой решения и планом работ, а не с общими формулировками, нужен срез текущей конфигурации. Чем точнее вводные, тем меньше уточняющих итераций: оценка опирается на реальные процессы, а не на предположения о них.
Пришлите то, что есть — этого достаточно для первой версии плана:
- перечень сервисов: имена программ, команды запуска, рабочие каталоги, переменные окружения;
- порядок запуска и зависимости: что поднимается первым, что ждёт готовности базы, какие процессы должны жить в единственном экземпляре;
- текущие конфигурации, включая разбивку по отдельным файлам и каталогам;
- как сейчас решается перезапуск после падения и после перезагрузки узла: юнит systemd, скрипт или ручной старт;
- куда пишутся логи и сколько хранятся: вывод Supervisord или собственные файлы приложений;
- целевое окружение: один узел или несколько, контейнеры или машины, права сервисного пользователя;
- что болит сейчас: неподнимающиеся процессы, петли перезапусков, потерянные задачи, рост логов.
Из этого мы собираем карту процессов, предлагаем схему управления ими и отдаём план работ с этапами и порядком выката. Опишите задачу — вернёмся с оценкой и планом.







