patterngoMajor
HTTP server graceful shutdown
Viewed 0 times
graceful shutdownhttp.Server.ShutdownSIGTERMsignal handlingin-flight requestsserver shutdown
Error Messages
Problem
Calling os.Exit or letting main() return immediately kills in-flight HTTP requests. A graceful shutdown waits for active connections to complete.
Solution
Use http.Server.Shutdown with a context and signal handling:
func main() {
srv := &http.Server{Addr: ":8080", Handler: myHandler()}
// Start server in goroutine
go func() {
if err := srv.ListenAndServe(); err != http.ErrServerClosed {
log.Fatalf("ListenAndServe: %v", err)
}
}()
// Wait for interrupt signal
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
log.Println("Shutting down...")
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
log.Fatalf("Shutdown: %v", err)
}
log.Println("Server exited")
}Why
Shutdown closes the listener immediately (no new connections) then waits for active connections to finish. If the context deadline passes before all connections close, it returns an error.
Gotchas
- After Shutdown returns, the server cannot be restarted — create a new http.Server
- WebSocket connections are not closed by Shutdown — they must be explicitly managed
- ListenAndServe returns http.ErrServerClosed on clean shutdown — this is not an error and should not be logged as one
Revisions (0)
No revisions yet.