Graceful Shutdowns в Go HTTP-серверах: как обеспечить 0 простоев при живом трафике
Graceful shutdown - это “прощание с клиентами”, когда сервер:
- перестаёт принимать новые запросы
- даёт завершиться текущим запросам
- чистит ресурсы (базы, файлы и т.д.)
- и только потом закрывается
Зачем это нужно:
Если просто “убить” сервер:
- запросы могут оборваться на полпути (например, оплата)
- пользователи получат ошибки или потеряют данные
- могут остаться “висячие” соединения и утечки ресурсов
Graceful shutdown решает это, особенно важно при деплое, перезагрузках, работе в Kubernetes/Docker.
# Как это сделать в Go
1. Использовать http.Server.Shutdown(ctx)
- сервер перестаёт принимать новые запросы, но завершает текущие в рамках таймаута.
2. Перехватывать сигналы ОС (`SIGINT`, SIGTERM`) через `os/signal
, чтобы начать shutdown.
3. Использовать context.WithTimeout
, чтобы ограничить время завершения.
4. Корректно закрывать ресурсы: БД, логи, файлы и т.д.
# Пример кода
package main
import (
"context"
"log"
"net/http"
"os"
"os/signal"
"time"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
time.Sleep(3 * time.Second)
w.Write([]byte("Request done"))
})
server := &http.Server{
Addr: ":8080",
Handler: mux,
}
go func() {
log.Println("Server starting on :8080")
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("ListenAndServe error: %v", err)
}
}()
stop := make(chan os.Signal, 1)
signal.Notify(stop, os.Interrupt, os.Kill)
log.Println("Shutting down server...")
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := server.Shutdown(ctx); err != nil {
log.Fatalf("Forced shutdown: %v", err)
}
log.Println("Server exited gracefully")
}
Вывод
- Graceful shutdown — не просто “красивость”, а необходимая практика для надёжных Go-сервисов:
- минимизирует потери данных и ошибок для пользователей
- обеспечивает корректное завершение внутренних операций
- делает деплой и перезапуск безопасными и незаметными
https://blog.stackademic.com/graceful-shutdowns-in-go-http-servers-ensuring-zero-downtime-for-live-traffic-b8224b28ab4a