転載元:https://juejin.cn/post/7212786062224146487
Gin は非常に人気のある Web フレームワークであり、高性能で保守が容易な Web アプリケーションを構築するためによく使用されます。ドメイン駆動設計 (DDD) やマイクロサービスでも広く使用されています。ただし、他のアプリケーションと同様に、Gin
Web サービスを停止する必要がある場合は、異常または不規則なサービスの終了を避けるために、接続の終了やメモリの解放などの問題に対処する必要があります。この記事では、Gin フレームワークを使用して正常に終了する方法を紹介します。
優雅な退出の原則
Golang Web サービスを停止する従来の方法は、TCP 接続を閉じる API を呼び出すことです。問題は、現時点でリクエストが HTTP リクエストを処理している場合、go コルーチンが終了していないためにリクエストが終了し、リソース リークやその他の問題が発生することです。
正常に停止する方法は、システム信号 (ctrl+c など) をリッスンした後に特定の HTTP サーバーを閉じ、アクティブな接続 (アドバイザリ TCP クローズ) が要求されたすべてのデータ交換を完了するのを待ってから切断します。これにより、各クライアントを適切にシャットダウンできるようになります。
Gin フレームワークは正常に終了します
Gin フレームワークはサーバー インターフェイスを提供するため、Gin アプリケーションで正常な終了をより簡単に実装できます。このアプリケーションでは、Shutdown(duration) メソッドを使用して、停止信号をリッスンするときに HTTP サーバーを安全に停止できます。
以下は、正常な終了を実現する方法を示す単純な Jin アプリケーションです。
package main
import (
"context"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/", func(c *gin.Context) {
time.Sleep(time.Second * 5)
c.JSON(http.StatusOK, gin.H{
"message": "Hello, World!"})
})
//创建HTTP服务器
server := &http.Server{
Addr: ":8080",
Handler: r,
}
//启动HTTP服务器
go func() {
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("listen: %s\n", err)
}
}()
//等待一个INT或TERM信号
quit := make(chan os.Signal)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
log.Println("Shutdown Server ...")
//创建超时上下文,Shutdown可以让未处理的连接在这个时间内关闭
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
//停止HTTP服务器
if err := server.Shutdown(ctx); err != nil {
log.Fatal("Server Shutdown:", err)
}
log.Println("Server exiting")
}
上の例では、Gin アプリケーションを作成し、クライアントからの HTTP リクエストを処理する HTTP サーバーを起動する main 関数を定義しました。
ここで重要なのは Shutdown() です。これはコンテキスト コンテキストを使用し、5 秒間待機して HTTP サーバーを正常にシャットダウンします。Shutdown メソッドは、HTTP サーバーを安全にシャットダウンしようとし、HTTP リクエストがタイムアウトになるまで接続を再配置するのを待ちます。
見てわかるように、コールバック関数は待機信号でハングします。その後、SIGTERM または SIGINT 信号を参照して終了します。これにより、プログラムはサーバーのシャットダウンに関する情報を出力し、Shutdown を呼び出してサーバーを安全にシャットダウンして正常に終了します。
結論は
この記事では、Gin フレームワークがどのように正常な終了を実現するかを説明しました。サービスを停止するときは、すべての接続を閉じ、クライアントのネゴシエーションとの適切な対話を確保しながらリソース リークを回避するために、閉じるときに必ずクリーンアップする必要があります。この完全なコードでは、SIGTERM シグナルと SIGINT シグナルを使用して、オペレーティング システムの便利なキャッチャー コールバックから Web サーバーを停止し、タイムアウト コンテキストを使用して、指定された時間が経過した後に正常にシャットダウンします。
注: 実際のアプリケーションでは、サーバーをシャットダウンする前にすべてのリクエストが確実に処理されるように、タイムアウト コンテキストなどのより厳密なコンテキストを使用する必要があります。