Какой командой можно убить процесс
Что проверяют
Знаете ли вы, что kill не «убивает», а отправляет сигнал, и чем отличаются SIGTERM и SIGKILL. Для Go-разработчика следом почти всегда идёт вопрос: как ваш сервис обрабатывает сигнал остановки и что происходит при деплое в Kubernetes.
Как отвечать
kill PID шлёт процессу сигнал, по умолчанию SIGTERM (15). Варианты по нарастающей:
SIGTERM: просьба завершиться. Процесс может перехватить сигнал, дописать ответы, закрыть соединения и выйти;SIGINT(2): то же, что прилетает от Ctrl+C в терминале;SIGKILL(kill -9): ядро снимает процесс без предупреждения. Перехватить его нельзя, поэтому ниdefer, ни обработчики не выполнятся;- поиск и массовые варианты:
pgrep -f имянайдёт PID,pkillиkillallотправят сигнал по имени,kill -0 PIDпроверит, жив ли процесс и хватает ли прав, ничего не отправляя.
Связка с Go. В main подписываются на сигналы через signal.NotifyContext(ctx, os.Interrupt, syscall.SIGTERM), а когда контекст отменён, вызывают http.Server.Shutdown(ctx) с таймаутом: сервер перестаёт принимать новые соединения и дожидается текущих запросов. Из программы другому процессу сигнал шлют через os.Process.Signal, а Process.Kill() на Unix отправляет именно SIGKILL.
Kubernetes при удалении пода шлёт SIGTERM, ждёт terminationGracePeriodSeconds (по умолчанию 30 секунд) и только потом SIGKILL. docker stop устроен так же, с ожиданием 10 секунд.
Где спотыкаются
Сразу отвечают kill -9. Это последний довод: процесс не закроет транзакции, а данные из буферов программы пропадут. Правильный порядок: SIGTERM, пауза, и только потом SIGKILL.
Не обрабатывают сигнал в сервисе. Без Shutdown Go-приложение при SIGTERM просто завершается, и запросы, которые были в работе во время деплоя, получают обрыв соединения.
Удивляются, что процесс не умирает даже от -9. Зомби уже завершился и ждёт, пока родитель прочитает его статус, а процесс в состоянии D висит в непрерываемом ожидании ввода-вывода. Сигнал тут бессилен, смотреть надо на родителя или на диск.