Golang / GoLang Production Patterns and Web Standards Interview Questions
How do you implement graceful shutdown of an HTTP server in Go?
Graceful shutdown means: stop accepting new connections, wait for in-flight requests to complete, then exit. This prevents data loss and connection resets for clients whose requests are mid-flight when a deployment or restart occurs.
func main() { srv := &http.Server{ Addr: ":8080", Handler: buildRouter(), } // Start server in background serverErr := make(chan error, 1) go func() { log.Println("listening on :8080") if err := srv.ListenAndServe(); err != nil { serverErr <- err } }() // Wait for shutdown signal or server error shutdown := make(chan os.Signal, 1) signal.Notify(shutdown, syscall.SIGINT, syscall.SIGTERM) select { case err := <-serverErr: if !errors.Is(err, http.ErrServerClosed) { log.Fatalf("server error: %v", err) } case sig := <-shutdown: log.Printf("received signal: %v â shutting down", sig) } // Give in-flight requests up to 30s to complete ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() if err := srv.Shutdown(ctx); err != nil { // Deadline exceeded: force close remaining connections log.Printf("forced shutdown: %v", err) srv.Close() } // Clean up other resources db.Close() log.Println("shutdown complete") } // In Kubernetes: SIGTERM is sent ~30s before SIGKILL // The 30s graceful period must be < terminationGracePeriodSeconds // Also set preStop lifecycle hook to delay pod removal from endpoints
More Related questions...