最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go項目實現(xiàn)優(yōu)雅關(guān)機與平滑重啟功能

 更新時間:2022年10月06日 09:06:49   作者:qi66  
無論是優(yōu)雅關(guān)機還是優(yōu)雅重啟歸根結(jié)底都是通過監(jiān)聽特定系統(tǒng)信號,然后執(zhí)行一定的邏輯處理保障當前系統(tǒng)正在處理的請求被正常處理后再關(guān)閉當前進程,這篇文章主要介紹了Go實現(xiàn)優(yōu)雅關(guān)機與平滑重啟 ,需要的朋友可以參考下

前言

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

什么是優(yōu)雅關(guān)機?

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

實現(xiàn)原理

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

實現(xiàn)優(yōu)雅重啟

package main

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

func main() {
	//啟動服務(優(yōu)雅關(guān)機)
	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)
		}
	}()
	// 等待中斷信號來優(yōu)雅地關(guān)閉服務器,為關(guān)閉服務器操作設置一個5秒的超時
	quit := make(chan os.Signal, 1) // 創(chuàng)建一個接收信號的通道
	// kill 默認會發(fā)送 syscall.SIGTERM 信號
	// kill -2 發(fā)送 syscall.SIGINT 信號,我們常用的Ctrl+C就是觸發(fā)系統(tǒng)SIGINT信號
	// kill -9 發(fā)送 syscall.SIGKILL 信號,但是不能被捕獲,所以不需要添加它
	// signal.Notify把收到的 syscall.SIGINT或syscall.SIGTERM 信號轉(zhuǎn)發(fā)給quit
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) // 此處不會阻塞
	<-quit                                               // 阻塞在此,當接收到上述兩種信號時才會往下執(zhí)行
	zap.L().Info("Shutdown Server ...")
	// 創(chuàng)建一個5秒超時的context
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	// 5秒內(nèi)優(yōu)雅關(guān)閉服務(將未處理完的請求處理完再關(guān)閉服務),超過5秒就超時退出
	if err := srv.Shutdown(ctx); err != nil {
		zap.L().Fatal("Server Shutdown: ", zap.Error(err))
	}
	zap.L().Info("Server exiting")
}

實現(xiàn)平滑重啟

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服務器會監(jiān)聽下列信號:
	// syscall.SIGHUP,syscall.SIGUSR1,syscall.SIGUSR2,syscall.SIGINT,syscall.SIGTERM和syscall.SIGTSTP
	// 接收到 SIGHUP 信號將觸發(fā)`fork/restart` 實現(xiàn)優(yōu)雅重啟(kill -1 pid會發(fā)送SIGHUP信號)
	// 接收到 syscall.SIGINT或syscall.SIGTERM 信號將觸發(fā)優(yōu)雅關(guān)機
	// 接收到 SIGUSR2 信號將觸發(fā)HammerTime
	// SIGUSR1 和 SIGTSTP 被用來觸發(fā)一些用戶自定義的hook函數(shù)
	if err := endless.ListenAndServe(":8080", router); err!=nil{
		log.Fatalf("listen: %s\n", err)
	}

	log.Println("Server exiting...")

測試

我們通過執(zhí)行kill -1 pid命令發(fā)送syscall.SIGINT來通知程序優(yōu)雅重啟,具體做法如下:

  • 打開終端,go build -o graceful_restart編譯并執(zhí)行./graceful_restart,終端輸出當前pid(假設為43682)
  • 將代碼中處理請求函數(shù)返回的hello gin!修改為hello q1mi!,再次編譯go build -o graceful_restart
  • 打開一個瀏覽器,訪問127.0.0.1:8080/,此時瀏覽器白屏等待服務端返回響應。
  • 在終端迅速執(zhí)行kill -1 43682命令給程序發(fā)送syscall.SIGHUP信號
  • 等第3步瀏覽器收到響應信息hello gin!后再次訪問127.0.0.1:8080/會收到hello q1mi!的響應。
  • 在不影響當前未處理完請求的同時完成了程序代碼的替換,實現(xiàn)了優(yōu)雅重啟。

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

總結(jié)

無論是優(yōu)雅關(guān)機還是優(yōu)雅重啟歸根結(jié)底都是通過監(jiān)聽特定系統(tǒng)信號,然后執(zhí)行一定的邏輯處理保障當前系統(tǒng)正在處理的請求被正常處理后再關(guān)閉當前進程。使用優(yōu)雅關(guān)機還是使用優(yōu)雅重啟以及怎么實現(xiàn),這就需要根據(jù)項目實際情況來決定了。

到此這篇關(guān)于Go實現(xiàn)優(yōu)雅關(guān)機與平滑重啟 的文章就介紹到這了,更多相關(guān)Go關(guān)機與重啟 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Golang中的錯誤處理深入分析

    Golang中的錯誤處理深入分析

    Go錯誤處理類似C語言,沒有提供任何異常,以及類java語言使用的try/catch異常處理機制。Go異常處理僅簡化為預定義的Error類型,Go沒有提供異常處理機制,不能拋出類似許多其他語言的異常。相反,Golang集成了新的錯誤處理機制,如panic和recovery
    2023-01-01
  • golang解壓帶密碼的zip包的方法詳解

    golang解壓帶密碼的zip包的方法詳解

    ZIP 文件格式是一種常用的壓縮和歸檔格式,用于將多個文件和目錄打包到一個單獨的文件中,同時對其內(nèi)容進行壓縮以減少文件大小,golang zip包的解壓有官方的zip包(archive/zip),但是官方給的zip解壓包代碼只有解壓不帶密碼的zip包,下面給出解壓操作的封裝
    2024-07-07
  • 詳解Go語言中for range的

    詳解Go語言中for range的"坑"

    這篇文章主要介紹了詳解Go語言中for range的"坑",文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-09-09
  • 詳解Golang實現(xiàn)http重定向https的方式

    詳解Golang實現(xiàn)http重定向https的方式

    這篇文章主要介紹了詳解Golang實現(xiàn)http重定向https的方式,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-08-08
  • GoFrame框架gset使用對比PHP?Java?Redis優(yōu)勢

    GoFrame框架gset使用對比PHP?Java?Redis優(yōu)勢

    這篇文章主要為大家介紹了GoFrame框架gset對比PHP?Java?Redis的使用優(yōu)勢詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • 深入理解Golang channel的應用

    深入理解Golang channel的應用

    channel是用于 goroutine 之間的同步、通信的數(shù)據(jù)結(jié)構(gòu)。它為程序員提供了更高一層次的抽象,封裝了更多的功能,這樣并發(fā)編程變得更加容易和安全。本文通過示例為大家詳細介紹了channel的應用,需要的可以參考一下
    2022-10-10
  • golang程序使用alpine編譯出最小arm鏡像實現(xiàn)

    golang程序使用alpine編譯出最小arm鏡像實現(xiàn)

    這篇文章主要為大家介紹了golang程序使用alpine編譯出最小arm鏡像,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12
  • goland?-sync/atomic原子操作小結(jié)

    goland?-sync/atomic原子操作小結(jié)

    這篇文章主要介紹了goland?-sync/atomic原子操作,原子操作能夠保證執(zhí)行期間是連續(xù)且不會被中斷(變量不會被其他修改,mutex可能存在被其他修改的情況),本文給大家介紹的非常詳細,需要的朋友參考下
    2022-08-08
  • Golang獲取當前時間代碼

    Golang獲取當前時間代碼

    本文給大家匯總介紹了golang中的相關(guān)的時間的操作,有需要的小伙伴可以拿走參考下
    2018-10-10
  • 詳解如何解決golang定時器引發(fā)的id重復問題

    詳解如何解決golang定時器引發(fā)的id重復問題

    這篇文章主要為大家詳細介紹了如何解決golang定時器引發(fā)的id重復問題,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2024-04-04

最新評論

瓮安县| 卫辉市| 容城县| 岫岩| 博野县| 田东县| 长武县| 大丰市| 兴安盟| 东乌| 天全县| 讷河市| 青川县| 镇平县| 台前县| 延吉市| 淳化县| 嘉义市| 阳东县| 巨野县| 广宗县| 郯城县| 张家川| 东宁县| 莒南县| 章丘市| 南丹县| 鄄城县| 岱山县| 吕梁市| 塘沽区| 高台县| 遂昌县| 商都县| 斗六市| 山西省| 连南| 渭源县| 富顺县| 永康市| 西乌珠穆沁旗|