Posted on February 8, 2020
| 3 minutes
| 431 words
| appleboy
我們該如何升級 Web 服務,你會說很簡單啊,只要關閉服務,上程式碼,再開啟服務即可,可是很多時候開發者可能沒有想到現在服務上面是否有正在處理的資料,像是購物車交易?也或者是說背景有正在處理重要的事情,如果強制關閉服務,就會造成下次啟動時會有一些資料上的差異,那該如何優雅地關閉服務,這就是本篇的重點了。底下先透過簡單的 gin http 服務範例介紹簡單的 web 服務
// +build go1.8packagemainimport("context""log""net/http""os""os/signal""syscall""time""github.com/gin-gonic/gin")funcmain(){router:=gin.Default()router.GET("/",func(c*gin.Context){time.Sleep(5*time.Second)c.String(http.StatusOK,"Welcome Gin Server")})srv:=&http.Server{Addr:":8080",Handler:router,}gofunc(){// service connectionsiferr:=srv.ListenAndServe();err!=nil&&err!=http.ErrServerClosed{log.Fatalf("listen: %s\n",err)}}()// Wait for interrupt signal to gracefully shutdown the server with// a timeout of 5 seconds.quit:=make(chanos.Signal,1)// kill (no param) default send syscall.SIGTERM// kill -2 is syscall.SIGINT// kill -9 is syscall.SIGKILL but can't be catch, so don't need add itsignal.Notify(quit,syscall.SIGINT,syscall.SIGTERM)<-quitlog.Println("Shutdown Server ...")ctx,cancel:=context.WithTimeout(context.Background(),5*time.Second)defercancel()iferr:=srv.Shutdown(ctx);err!=nil{log.Fatal("Server Shutdown: ",err)}log.Println("Server exiting")}