TGViewer
Библиотека Go-разработчика | Golang Библиотека Go-разработчика | Golang @goproglib · 24.1K subscribers
Post #7286 3.1K
🌃 Graceful Shutdown в Go: http.Server.Shutdown

Обработка сигналов позволяет среагировать на завершение работы. Но она не ждёт текущие запросы. Чтобы это исправить, в Go есть server.Shutdown().

❔ Как это работает

Создаём http.Server явно и используем его метод Shutdown:
package main

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

func handler(w http.ResponseWriter, r *http.Request) {
fmt.Println("handling request...")
time.Sleep(5 * time.Second)
fmt.Fprintln(w, "done")
}

func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", handler)

server := &http.Server{
Addr: ":8080",
Handler: mux,
}

go func() {
fmt.Println("server started at :8080")
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
panic(err)
}
}()

ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()

<-ctx.Done()
fmt.Println("shutdown signal received")

shutdownCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

server.Shutdown(shutdownCtx)

fmt.Println("graceful shutdown complete")
}


Ключевой блок:
shutdownCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

server.Shutdown(shutdownCtx)


server.Shutdown() останавливает приём новых соединений и ждёт, пока текущие запросы завершатся. Таймаут контекста страхует от зависания — если через 10 секунд что-то ещё не завершилось, процесс всё равно выйдет.

🔍 Что остаётся нерешённым

Есть небольшое окно между получением сигнала и вызовом Shutdown. В это время сервер всё ещё принимает новые соединения. При высокой нагрузке это может привести к непредсказуемому поведению — часть запросов получит ответ, часть будет оборвана.

server.Shutdown() решает главную проблему — in-flight запросы дожидаются завершения. Для большинства сервисов этого достаточно. Но если нужна полная управляемость трафиком во время shutdown, нужен ещё один слой.

📍 Навигация: Вакансии • Задачи • Собесы • Канал в Max

🐸 Библиотека Go-разработчика

#GoToProduction
  • 👍 11
More from @goproglib
  1. Sep 28, 2026🤔 Вопрос с собеседования по Go Что выведет программа? ❤️ — 1 true / 0 false 🔥 — 1 true /…
  2. Sep 28, 2026👩‍💻 Что на самом деле происходит внутри Go map? После Go 1.24 обычный map внутри работае…
  3. Sep 26, 2026🔥 В Go 1.27 появился portable SIMD До этого SIMD-оптимизации в Go требовали архитектурног…
  4. Sep 25, 2026🤡🤡 📍 Навигация: Вакансии • Задачи • Собесы 🐸 Библиотека Go-разработчика #GoGiggle
  5. Sep 25, 2026💡 Код работает. А data race уже есть В Go можно записать значение в одной горутине, прочи…
  6. Sep 23, 2026💥 TCP/IP: что происходит с данными в сети Когда Go-приложение отправляет данные по сети,…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →