Корректная остановка сервиса
Вопрос
Как правильно останавливать процесс сервиса и что должно делать приложение, чтобы остановка была корректной?
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Сначала SIGTERM, затем ожидание (таймаут), и только потом SIGKILL
Приложение ловит SIGTERM: перестаёт принимать новые запросы, дожидается текущих, закрывает соединения с БД
SIGKILL нельзя перехватить, поэтому после него остаются lock-файлы и незавершённые операции
systemd делает так же: `KillSignal`, `TimeoutStopSec`, затем SIGKILL
В контейнере процесс должен быть PID 1 или запускаться через init (tini), иначе сигнал не дойдёт
Код выхода 143 после SIGTERM и 137 после SIGKILL помогают понять, как завершился процесс
Что могут спросить следом
- Почему процесс в контейнере может игнорировать SIGTERM?
- Что делает Kubernetes при удалении пода?
- Чем SIGHUP полезен демонам?
Разбор
Остановка в два этапа. Сначала отправляем SIGTERM: это просьба, которую приложение может обработать. Хороший обработчик перестаёт принимать новые соединения, дожидается текущих запросов, коммитит или откатывает транзакции, закрывает пулы и выходит с кодом 0. Если за отведённое время процесс не вышел, отправляем SIGKILL, который перехватить нельзя. systemd делает ровно это: шлёт KillSignal (по умолчанию SIGTERM), ждёт TimeoutStopSec, потом SIGKILL. Kubernetes так же: SIGTERM, затем terminationGracePeriodSeconds, по умолчанию 30 секунд, затем SIGKILL. Ловушка в контейнерах: у PID 1 в Linux нет действий по умолчанию для сигналов, и если приложение запущено через sh -c или не ставит обработчик, SIGTERM будет проигнорирован, и через 30 секунд контейнер убьют жёстко. Лечится exec-формой CMD или маленьким init вроде tini.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.