Graceful restart or stop

Do you want to graceful restart or stop your web server? There are some ways this can be done.

We can use fvbock/endless to replace the default ListenAndServe. Refer issue #296 for more details.

  1. router := gin.Default()
  2. router.GET("/", handler)
  3. // [...]
  4. endless.ListenAndServe(":4242", router)

An alternative to endless:

  • manners: A polite Go HTTP server that shuts down gracefully.
  • graceful: Graceful is a Go package enabling graceful shutdown of an http.Handler server.
  • grace: Graceful restart & zero downtime deploy for Go servers.

If you are using Go 1.8, you may not need to use this library! Consider using http.Server’s built-in Shutdown() method for graceful shutdowns. See the full graceful-shutdown example with gin.

  1. // +build go1.8
  2. package main
  3. import (
  4. "context"
  5. "log"
  6. "net/http"
  7. "os"
  8. "os/signal"
  9. "syscall"
  10. "time"
  11. "github.com/gin-gonic/gin"
  12. )
  13. func main() {
  14. router := gin.Default()
  15. router.GET("/", func(c *gin.Context) {
  16. time.Sleep(5 * time.Second)
  17. c.String(http.StatusOK, "Welcome Gin Server")
  18. })
  19. srv := &http.Server{
  20. Addr: ":8080",
  21. Handler: router,
  22. }
  23. go func() {
  24. // service connections
  25. if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
  26. log.Fatalf("listen: %s\n", err)
  27. }
  28. }()
  29. // Wait for interrupt signal to gracefully shutdown the server with
  30. // a timeout of 5 seconds.
  31. quit := make(chan os.Signal)
  32. // kill (no param) default send syscanll.SIGTERM
  33. // kill -2 is syscall.SIGINT
  34. // kill -9 is syscall. SIGKILL but can"t be catch, so don't need add it
  35. signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
  36. <-quit
  37. log.Println("Shutdown Server ...")
  38. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
  39. defer cancel()
  40. if err := srv.Shutdown(ctx); err != nil {
  41. log.Fatal("Server Shutdown:", err)
  42. }
  43. // catching ctx.Done(). timeout of 5 seconds.
  44. select {
  45. case <-ctx.Done():
  46. log.Println("timeout of 5 seconds.")
  47. }
  48. log.Println("Server exiting")
  49. }

Last modified March 7, 2020 : add blog dir (#115) (f46734b)