91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Go如何實現優雅關機與平滑重啟功能

發布時間:2022-10-10 14:25:03 來源:億速云 閱讀:150 作者:iii 欄目:開發技術

這篇“Go如何實現優雅關機與平滑重啟功能”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Go如何實現優雅關機與平滑重啟功能”文章吧。

什么是優雅關機?

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

實現原理

Go 1.8版本之后, http.Server 內置的 Shutdown() 方法就支持優雅地關機,說明一下Shutdown工作的機制:當程序檢測到中斷信號時,我們調用http.server種的shutdown方法,該方法將阻止新的請求進來,同時保持當前的連接,知道當前連接完成則終止程序!

實現優雅重啟

package main

import (
	"context"
	"fmt"
	"github.com/spf13/viper"
	"go.uber.org/zap"
	"log"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"
)

func main() {
	//啟動服務(優雅關機)
	srv := &http.Server{
		Addr:    fmt.Sprintf(":%d", viper.GetInt("app.port")),
		Handler: r,
	}
	go func() {
		// 開啟一個goroutine啟動服務
		if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Fatalf("listen: %s\n", err)
		}
	}()
	// 等待中斷信號來優雅地關閉服務器,為關閉服務器操作設置一個5秒的超時
	quit := make(chan os.Signal, 1) // 創建一個接收信號的通道
	// kill 默認會發送 syscall.SIGTERM 信號
	// kill -2 發送 syscall.SIGINT 信號,我們常用的Ctrl+C就是觸發系統SIGINT信號
	// kill -9 發送 syscall.SIGKILL 信號,但是不能被捕獲,所以不需要添加它
	// signal.Notify把收到的 syscall.SIGINT或syscall.SIGTERM 信號轉發給quit
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) // 此處不會阻塞
	<-quit                                               // 阻塞在此,當接收到上述兩種信號時才會往下執行
	zap.L().Info("Shutdown Server ...")
	// 創建一個5秒超時的context
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	// 5秒內優雅關閉服務(將未處理完的請求處理完再關閉服務),超過5秒就超時退出
	if err := srv.Shutdown(ctx); err != nil {
		zap.L().Fatal("Server Shutdown: ", zap.Error(err))
	}
	zap.L().Info("Server exiting")
}

實現平滑重啟

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) {
		c.String(http.StatusOK, "hello xiaosheng !")
	})
	// 默認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...")

測試

我們通過執行kill -1 pid命令發送syscall.SIGINT來通知程序優雅重啟,具體做法如下:

  • 打開終端,go build -o graceful_restart編譯并執行./graceful_restart,終端輸出當前pid(假設為43682)

  • 將代碼中處理請求函數返回的hello gin!修改為hello q1mi!,再次編譯go build -o graceful_restart

  • 打開一個瀏覽器,訪問127.0.0.1:8080/,此時瀏覽器白屏等待服務端返回響應。

  • 在終端迅速執行kill -1 43682命令給程序發送syscall.SIGHUP信號

  • 等第3步瀏覽器收到響應信息hello gin!后再次訪問127.0.0.1:8080/會收到hello q1mi!的響應。

  • 在不影響當前未處理完請求的同時完成了程序代碼的替換,實現了優雅重啟。

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

以上就是關于“Go如何實現優雅關機與平滑重啟功能”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

go
AI

明水县| 航空| 苏州市| 中西区| 乐山市| 舟曲县| 青铜峡市| 拉萨市| 桂林市| 三台县| 华安县| 泸西县| 额尔古纳市| 棋牌| 大庆市| 涟源市| 扶绥县| 横山县| 丰宁| 岗巴县| 高清| 乐都县| 青河县| 股票| 中阳县| 阿鲁科尔沁旗| 长治县| 阳原县| 新平| 于田县| 平凉市| 夹江县| 南阳市| 张家口市| 佛坪县| 禹城市| 交口县| 榕江县| 杭锦旗| 金溪县| 大理市|