智慧線上客服系統原始碼GOFLY開發日誌-6. gin框架的優雅退出

taoshihan發表於2022-02-17

開發好專案後,也能正常執行起來了,但是怎麼退出才算優雅的退出呢。

一般情況下,執行命令列的前臺程式,直接按ctrl+c程式就退出了,這不算是優雅的退出。網上的資料裡,優雅退出gin程式,是需要處理下ctrl+c時候的程式訊號,然後處理完所有請求在退出。

呼叫http實現優雅退出

我實現的是,通過呼叫一下http介面,就能觸發程式退出,再配合上守護程式模式,子程式會被自動重啟,相當於是重啟服務了。也是在前面訊號量的基礎上修改了一點點,就實現了這個效果。

首先需要先修改下gin最後run方法那裡,需要包裝一下

    baseServer := "0.0.0.0:" + port
    engine := gin.Default()
    //engine.Run(baseServer)
    srv := &http.Server{
        Addr:    baseServer,
        Handler: engine,
    }

    go func() {
        if err := srv.ListenAndServe(); err != nil {
            log.Printf("GOFLY服務監聽: %s\n", err)
        }
    }()

    <-controller.StopSign
    log.Println("關閉服務...")
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()
    if err := srv.Shutdown(ctx); err != nil {
        log.Fatal("服務關閉失敗:", err)
    }
    log.Println("服務已關閉")

上面程式碼裡,就是把監聽方法的阻塞放在了一個groutine裡,主groutine被<-stopSign這個讀取通道的指令阻塞住。

然後在http路由裡,往stopSign這個channel發訊息,主groutine收到訊息,就執行後面的關閉程式

systemGroup.GET("/stop", controller.GetStop)
package controller

import (
    "github.com/gin-gonic/gin"
)

var StopSign = make(chan int)

func GetStop(c *gin.Context) {

    StopSign <- 1

    c.JSON(200, gin.H{
        "code": 200,
        "msg":  "ok",
    })
}

後面還遇到了哪些問題和知識點將會繼續進行總結。

演示網站:
gofly.sopans.com

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章