Golang中的Graceful Shutdown
前言 最近在學習Golang,在架設http server時,發現Golang在v1.8推出了一個叫做Graceful Shutdown的功能,說來慚愧,先前寫的幾個小專案雖然也都是http server,卻沒有使用過像這樣的功能,所以用一篇小文章來記錄一下。 什麼是Graceful Shutdown? 先想像一下今天已經有一個已經上線的電商網站服務,使用者會在這個網站上面瀏覽、購買商品,當這個網站要升版時,服務就必須暫停 — — 意思是,所有還在網站上進行的交易、連線都會被中斷。若是像這樣強制關閉服務,待下一次服務啟動時,我們可能就會發現資料上會有預期外的錯誤與差異。 Graceful Shutdown直譯來說就是「優雅地關機」,這個意思是,當伺服器收到終止的指令後,如果手上還有正在執行的process,它會先處理完,之後才會真的關閉服務,這麼作不僅可以保障資料的一致與完整性,我們也不需要害怕突然中止程式可能會導致非預期的錯誤。 普通的HTTP server 以下我會先介紹「沒有」Graceful Shutdown機制且強制關閉服務的觀察現象,在這邊,HTTP server的實作會透過Gin framework來實現。 package main import ( "log" "net/http" "time" "github.com/gin-gonic/gin" ) func main() { log.Println("starting server...") router := gin.Default() router.GET("/", func(c *gin.Context) { time.Sleep(10 * time.Second) c.String(http.StatusOK, "hello there") }) srv := &http.Server{ Addr: ":8080", Handler: router, } srv.ListenAndServe() } 根據以上設計,當我們前往localhost:8080後,等十秒會收到從server回傳的字串;若我們在這十秒內強制中止server,client連線也就會跟著被強制中斷,導致終端機噴出以下錯誤: * Empty reply from server * Closing connection 0 curl: (52) Empty reply from server Graceful Shutdown in HTTP server 前一次實驗的錯誤是因為當我們結束server服務時,還有一個client連線還沒有收到預期的回覆,卻被強制中斷連線所導致的錯誤。...