Ответ
Команда kill
в Unix-подобных системах отправляет сигналы процессам. Вопреки названию, она не всегда "убивает" процесс, а лишь уведомляет его о событии.
Для бэкенд-разработчика наиболее важны следующие сигналы:
SIGTERM
(сигнал 15): Сигнал корректного завершения. Это сигнал по умолчанию дляkill
. Приложение должно перехватить этот сигнал и выполнить процедуру "graceful shutdown": закрыть сетевые соединения, завершить обработку текущих запросов, сохранить данные и т.д.kill <PID> # или kill -15 <PID>
SIGKILL
(сигнал 9): Сигнал принудительного завершения. Этот сигнал нельзя перехватить или проигнорировать. Ядро операционной системы немедленно завершает процесс. Используется как крайняя мера, когда процесс не отвечает наSIGTERM
.kill -9 <PID>
SIGHUP
(сигнал 1): Сигнал для перезагрузки конфигурации. Исторически означал разрыв соединения с терминалом, но сейчас часто используется для того, чтобы дать команду процессу перечитать свои конфигурационные файлы без перезапуска.
Реализация Graceful Shutdown в Go:
В Go для обработки сигналов используется пакет os/signal
. Типичный паттерн выглядит так:
import (
"context"
"os"
"os/signal"
"syscall"
)
func main() {
// ... запуск сервера или воркера ...
// Создаем канал для получения сигналов ОС
quit := make(chan os.Signal, 1)
// Уведомляем о получении SIGINT (Ctrl+C) или SIGTERM
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
// Блокируемся, пока не получим сигнал
<-quit
// ... начинаем процедуру graceful shutdown ...
// Например, вызываем server.Shutdown(ctx)
}