Sobes.tech
Назад к вопросам
Middle — Middle+
81

Какая последовательность действий необходима для корректного остановки приложения без потери данных или сбоев?

Компании, где спрашивали
WildberriesWildberries

Ответ от нейросети

sobes.tech AI

Для корректного остановки Go-приложения без потери данных и сбоев обычно выполняют следующие шаги:

  1. Обработка сигналов ОС — ловят сигналы завершения (SIGINT, SIGTERM) с помощью канала и signal.Notify.

  2. Инициация graceful shutdown — запускают процедуру плавного завершения, которая останавливает приём новых запросов и даёт текущим завершиться.

  3. Отмена контекста — используют context.Context с отменой, чтобы передать сигнал остановки всем горутинам.

  4. Закрытие ресурсов — закрывают открытые соединения с базами данных, файлы, сетевые соединения.

  5. Ожидание завершения работы горутин — с помощью sync.WaitGroup или других механизмов ждут, пока все операции завершатся.

Пример обработки сигнала и graceful shutdown:

import (
    "context"
    "os"
    "os/signal"
    "sync"
    "syscall"
    "time"
)

func main() {
    ctx, cancel := context.WithCancel(context.Background())
    var wg sync.WaitGroup

    // Запуск работы приложения
    wg.Add(1)
    go func() {
        defer wg.Done()
        runApp(ctx) // функция с основной логикой
    }()

    // Обработка сигналов
    sigs := make(chan os.Signal, 1)
    signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)

    <-sigs // ждём сигнал
    cancel() // отменяем контекст, сигнализируя горутинам

    // Ждём завершения
    done := make(chan struct{})
    go func() {
        wg.Wait()
        close(done)
    }()

    select {
    case <-done:
        // Все завершились
    case <-time.After(10 * time.Second):
        // Таймаут ожидания
    }
}

Такой подход позволяет избежать потери данных и некорректного завершения работы.