How do I implement graceful shutdown for HTTP servers?

In Go, implementing a graceful shutdown for HTTP servers allows you to handle ongoing requests and clean up resources before the server stops accepting new requests. This is particularly useful for scenarios like deploying new versions of your application, performing maintenance, or managing server health. Below is an example of how to achieve a graceful shutdown using Go's `http.Server` and the context package.

package main import ( "context" "log" "net/http" "os" "os/signal" "time" ) func main() { // Create a new HTTP server srv := &http.Server{ Addr: ":8080", Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello, World!")) }), } // Create a channel to listen for OS interrupt signals stop := make(chan os.Signal, 1) signal.Notify(stop, os.Interrupt) // Start the server in a goroutine go func() { if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Fatalf("ListenAndServe(): %v", err) } }() // Wait for an interrupt signal <-stop log.Println("Shutting down server...") // Create a context with a timeout for the shutdown ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() // Shutdown the server gracefully if err := srv.Shutdown(ctx); err != nil { log.Fatalf("Server Shutdown Failed:%+v", err) } log.Println("Server exited gracefully") }

Go HTTP server graceful shutdown Go context HTTP server management server lifecycle management