首頁  >  文章  >  後端開發  >  解析golang中如何優雅關閉http服務

解析golang中如何優雅關閉http服務

PHPz
PHPz原創
2023-04-11 10:43:281310瀏覽

Golang是一種非常流行的程式語言,它具有高效的並發處理能力和優秀的效能表現。相信許多golang的開發人員都會遇到這樣的問題,在golang中如何優雅地關閉http服務?

首先,我們要知道,建立一個http服務是比較容易的,只要幾行程式碼就可以搞定。例如下面這個簡單的範例:

package main

import (
    "fmt"
    "net/http"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintln(w, "Hello")
    })
    http.ListenAndServe(":8080", nil)
}

這裡我們新建了一個http服務,監聽本地的8080端口,每次訪問會返回一個"Hello"。但如何優雅的關閉此服務呢?

常用的方法是使用os.Signal管理服務的生命週期。 os.Signal是作業系統給行程發送的中斷訊號,例如Ctrl C等,目的是要求程式終止執行。在golang中,我們可以監聽這些訊號,然後在接收到訊號後執行一些鉤子函數,以優雅地關閉http服務。

具體實作如下:

package main

import (
    "context"
    "fmt"
    "net/http"
    "os"
    "os/signal"
    "syscall"
    "time"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintln(w, "Hello")
    })
    srv := &http.Server{Addr: ":8080"}

    signalChan := make(chan os.Signal, 1)
    signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM)

    go func() {
        sig := <-signalChan
        fmt.Printf("Signal Received: %s,  Gracefully shutting down...\n", sig)
        ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
        defer cancel()
        srv.Shutdown(ctx)
    }()

    fmt.Println("Server starting...")
    if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
        fmt.Printf("server start failed, err: %v\n", err)
        return
    }

    fmt.Println("Server closed.")
}

我們透過signal.Notify方法,註冊了兩個訊號,分別是Ctrl C和kill。然後,在main函數裡透過一個死循環等待訊號的到來。當訊號到來時,我們會先列印一行日誌,表示我們成功地接收到了一個訊號,然後我們會呼叫http.Server的Shutdown()方法,將http服務正常地關閉,這些操作都會在上下文中進行。

當我們傳遞一個context.Context物件到http.Server的Shutdown()方法時,http服務就會進入到優雅關閉的過程,Shutdown()方法的具體流程如下所示:

  1. Immediately return ErrServerClosed for all active connections.
  2. Call Shutdown on all active connections.
  3. Call Shutdown on the server's listener.
  4. ##Waait for all outit for all out associated with the server to complete.
#也就是說,在Shutdown()方法被呼叫後,所有的活躍連線會被立即關閉,同時新的連線請求也會被禁止。然後,Shutdown()方法會呼叫所有活躍連接的Shutdown()方法來關閉連接,這樣我們就可以保證所有的連接都被正常關閉了。最後,Shutdown()方法會關閉我們的http server,並關閉完成後,程式再退出。

透過這樣的優雅關閉方式,我們可以保證http服務在關閉時不會影響正在處理的請求,即使你正在完成HTTP請求時呼叫了Ctrl C也不會影響HTTP連線的效能。這樣做可以讓我們的程式更健壯、更可靠,非常適合用於生產環境中。

當然,這只是一個golang優雅關閉http服務的範例,你可以根據你的實際環境來進行修改,希望這篇文章能為你帶來幫助。

以上是解析golang中如何優雅關閉http服務的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn