Что делает команда `kill` и какие сигналы важны для бэкенд-разработчика?

Ответ

Команда 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)
}