golang 實現優雅的關機和重啟


優雅地關機

  優雅關機就是服務端關機命令發出后不是立即關機,而是等待當前還在處理的請求全部處理完畢后再退出程序,是一種對客戶端友好的關機方式。而執行Ctrl+C關閉服務端時,會強制結束進程導致正在訪問的請求出現問題。

 

golang實現優雅的關機

package main

import (
    "fmt"
    "net/http"
    "context"
    "log"
    "os"
    "os/signal"
    "time"


    "gin-blog/routers"
    "gin-blog/pkg/setting"
)

func main() {
    router := routers.InitRouter()

    s := &http.Server{
        Addr:           fmt.Sprintf(":%d", setting.HTTPPort),
        Handler:        router,
        ReadTimeout:    setting.ReadTimeout,
        WriteTimeout:   setting.WriteTimeout,
        MaxHeaderBytes: 1 << 20,
    }

    go func() {
        if err := s.ListenAndServe(); err != nil {
            log.Printf("Listen: %s\n", err)
        }
    }()
    
    quit := make(chan os.Signal)
    signal.Notify(quit, os.Interrupt)
    <- quit

    log.Println("Shutdown Server ...")

    ctx, cancel := context.WithTimeout(context.Background(), 5 * time.Second)
    defer cancel()
    if err := s.Shutdown(ctx); err != nil {
        log.Fatal("Server Shutdown:", err)
    }

    log.Println("Server exiting")
}

 

 

優雅地重啟

 

   

優雅關機實現了,那么該如何實現優雅重啟呢?

我們可以使用 fvbock/endless 來替換默認的 ListenAndServe啟動服務來實現, 示例代碼如下:

package main

import (
    "log"
    "net/http"
    "time"

    "github.com/fvbock/endless"
    "github.com/gin-gonic/gin"
)

func main() {
    router := gin.Default()
    router.GET("/", func(c *gin.Context) {
        time.Sleep(5 * time.Second)
        c.String(http.StatusOK, "hello gin!")
    })
    // 默認endless服務器會監聽下列信號:
    // syscall.SIGHUP,syscall.SIGUSR1,syscall.SIGUSR2,syscall.SIGINT,syscall.SIGTERM和syscall.SIGTSTP
    // 接收到 SIGHUP 信號將觸發`fork/restart` 實現優雅重啟(kill -1 pid會發送SIGHUP信號)
    // 接收到 syscall.SIGINT或syscall.SIGTERM 信號將觸發優雅關機
    // 接收到 SIGUSR2 信號將觸發HammerTime
    // SIGUSR1 和 SIGTSTP 被用來觸發一些用戶自定義的hook函數
    if err := endless.ListenAndServe(":8080", router); err!=nil{
        log.Fatalf("listen: %s\n", err)
    }

    log.Println("Server exiting")
}

但是需要注意的是,此時程序的PID變化了,因為endless 是通過fork子進程處理新請求,待原進程處理完當前請求后再退出的方式實現優雅重啟的。所以當你的項目是使用類似supervisor的軟件管理進程時就不適用這種方式了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM