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

Напишите механизм Graceful Shutdown для HTTP-сервера с использованием каналов и обработки сигналов ОС (Ctrl+C)

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

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

sobes.tech AI

Для реализации Graceful Shutdown HTTP-сервера в Go обычно используют канал для перехвата системных сигналов (например, SIGINT при нажатии Ctrl+C) и метод Shutdown из пакета net/http, который позволяет корректно завершить работу сервера, дождаться завершения активных запросов и освободить ресурсы.

Пример:

package main

import (
    "context"
    "log"
    "net/http"
    "os"
    "os/signal"
    "syscall"
    "time"
)

func main() {
    srv := &http.Server{Addr: ":8080"}

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Hello, world!"))
    })

    // Канал для получения сигналов ОС
    quit := make(chan os.Signal, 1)
    signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)

    go func() {
        <-quit
        log.Println("Shutting down server...")

        // Контекст с таймаутом для завершения работы
        ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
        defer cancel()

        if err := srv.Shutdown(ctx); err != nil {
            log.Fatalf("Server forced to shutdown: %v", err)
        }
    }()

    log.Println("Server is ready to handle requests at :8080")
    if err := srv.ListenAndServe(); err != http.ErrServerClosed {
        log.Fatalf("Could not listen on :8080: %v", err)
    }

    log.Println("Server stopped")
}

В этом примере сервер запускается и слушает порт 8080. При получении сигнала SIGINT или SIGTERM запускается процедура корректного завершения с таймаутом 5 секунд, в течение которых сервер завершает обработку текущих запросов.