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

golang 監(jiān)聽服務(wù)的信號,實現(xiàn)平滑啟動,linux信號說明詳解

 更新時間:2021年05月08日 09:22:29   作者:胖達(dá)喵  
這篇文章主要介紹了golang 監(jiān)聽服務(wù)的信號,實現(xiàn)平滑啟動,linux信號說明詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

監(jiān)聽服務(wù)的信號,實現(xiàn)平滑啟動,linux信號說明

package main 
import (
	"context"
	"fmt"
	"golang.org/x/sync/errgroup"
	"net/http"
	"os"
	"os/signal"
	"syscall"
) 
 
func main() { 
	g, ctx := errgroup.WithContext(context.Background())
	fmt.Println("服務(wù)啟動start!")
	addr := ":9091"
	s :=&http.Server{
		Addr: addr,
		Handler:http.DefaultServeMux,
	}
	g.Go(func() error {
		http.HandleFunc("/test1", func(writer http.ResponseWriter, request *http.Request) {
			fmt.Println("tes1")
			writer.Write([]byte("tes1"))
		})
		return s.ListenAndServe()
	})
	g.Go(func() error {
		exit := make(chan os.Signal)
		//監(jiān)聽 Ctrl+C 信號
		signal.Notify(exit, syscall.SIGINT, syscall.SIGTERM)
		select {
		case <-exit:
			fmt.Println("進(jìn)程已被取消~")
			return s.Shutdown(ctx)
		}
	})
	err := g.Wait()
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println("服務(wù)啟動成功!")
	if ctx.Err() !=nil {
		fmt.Println(ctx.Err())
		fmt.Println("服務(wù)關(guān)閉成功!")
		os.Exit(0)
	}
 
}

補充:golang http服務(wù)實現(xiàn)平滑重啟

看代碼吧~

package main 
import (
    "context"
    "encoding/json"
    "fmt"
    "math/rand"
    "net/http"
    "os"
    "os/signal"
    "time"
)
 
var logChan  = make(chan map[string]interface{}) 
var requestStatusMap = map[int]bool{}  
var done = make(chan bool, 1)
var quit = make(chan os.Signal, 1) 
 
//為什么這樣可以平滑重啟?
// 正常情況下是server.ListenAndServe() 這個位置hang住整個進(jìn)程的
// 可以把這個程序看成兩部分,1個是web服務(wù)的監(jiān)聽部分,一個是處理部分, 如果web服務(wù)器不開啟了,那么就不能處理新進(jìn)來的請求了(可以理解為一個帶路的)
// 真正讓這個請求斷掉  是因為主進(jìn)程(main)被kill
// 所以平滑重啟的原理就是,先kill掉web服務(wù)器,不讓新的請求進(jìn)來,等現(xiàn)有的全部請求完了,然后結(jié)束當(dāng)前進(jìn)程
func main() {
    server := newServer()
    signal.Notify(quit, os.Interrupt)
    go monitorKill(server, quit)
    server.ListenAndServe()
    <-done
} 
 
func newServer() *http.Server {
    router := http.NewServeMux()
    router.HandleFunc("/hello", sayHello)
    return &http.Server{
        Addr:         ":8262",
        Handler:      router,
    }
}
 
func monitorKill(server *http.Server, quit <-chan os.Signal)  {
    <-quit
    go shutDown(server)
    for {
        if len(requestStatusMap) != 0 {
            fmt.Println("目前還有進(jìn)行中的請求,請稍等")
            time.Sleep(time.Second * 1)
            continue
        } else {
            close(done)
            break
        }
    }
}
 
func shutDown(server *http.Server) {
    if err := server.Shutdown(context.Background()); err != nil {
        fmt.Println(err)
    }
}
 
func sayHello(w http.ResponseWriter, r *http.Request) {
    go WriteInfo()//請求寫日志
    var uniqueId = GenerateRangeNum(1, 1000)
    requestStatusMap[uniqueId] = false
    url := r.URL.Path
    query  := r.URL.RawQuery
    method := r.Method
    a := map[string] interface{}{
        "url" : url,
        "method" : method,
        "query" : query,
        "response": "hello world!",
    }
    logChan<-a
    w.Write([]byte("hello world!"))
    time.Sleep(time.Second * 10)
    delete(requestStatusMap, uniqueId)
}
 
func WriteInfo() {
    info := <-logChan
    fileName := "/tmp/weekhomework.log"
    _, err := os.Stat(fileName)
    if err != nil || os.IsNotExist(err) {
        _, _ = os.Create(fileName)
    }
    f,err := os.OpenFile(fileName, os.O_WRONLY, 0644)
    defer f.Close()
    if err !=nil {
        fmt.Println(err.Error())
    } else {
        //追加寫入   為什么O_APPEND 模式無法寫入? todo
        n, _ := f.Seek(0, 2)
        infostr, _ := json.Marshal(info)
        _,err=f.WriteAt([]byte(string(infostr) +"\n"), n)
    }
}
 
func GenerateRangeNum(min int, max int) int {
    if min == max {
        return min
    }
    rand.Seed(time.Now().Unix())
    randNum := rand.Intn(max-min) + min
    return randNum
}

主要思路:

對于每個請求都做記錄,處理完成之后做刪除。 用一個協(xié)程去監(jiān)控中斷信號,有中斷信號先把http服務(wù)關(guān)閉。

如果這個時候還有請求沒有處理完,那么就輪訓(xùn)等待,等全部處理完那么就 發(fā)出終止信號結(jié)束main進(jìn)程的執(zhí)行

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。

相關(guān)文章

  • go實現(xiàn)服務(wù)優(yōu)雅關(guān)閉的示例

    go實現(xiàn)服務(wù)優(yōu)雅關(guān)閉的示例

    本文主要介紹了go實現(xiàn)服務(wù)優(yōu)雅關(guān)閉的示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • 基于golang中container/list包的用法說明

    基于golang中container/list包的用法說明

    這篇文章主要介紹了基于golang中container/list包的用法說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • 深入學(xué)習(xí)Go延遲語句

    深入學(xué)習(xí)Go延遲語句

    本文主要介紹了深入學(xué)習(xí)Go延遲語句,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-06-06
  • go xorm框架的使用

    go xorm框架的使用

    xorm框架和Spring Data Jpa有點相似,可以對比學(xué)習(xí),對于這個框架感覺還不錯,閑暇時間學(xué)習(xí)一下
    2021-05-05
  • Go語言JSON數(shù)據(jù)返回的實戰(zhàn)案例

    Go語言JSON數(shù)據(jù)返回的實戰(zhàn)案例

    本文介紹用Go標(biāo)準(zhǔn)庫構(gòu)建返回JSON的HTTP接口,包括GET請求處理、JSON編碼及響應(yīng)設(shè)置,為RESTful API開發(fā)打下基礎(chǔ),感興趣的可以了解一下
    2025-08-08
  • go語言中的map如何解決散列性能下降

    go語言中的map如何解決散列性能下降

    近期對go語言的map進(jìn)行深入了解和探究,其中關(guān)于map解決大量沖突的擴容操作設(shè)計的十分巧妙,所以筆者特地整理了這篇文章來探討一下go語言中map如何解決散列性能下降,文中有相關(guān)的代碼示例供大家參考,需要的朋友可以參考下
    2024-03-03
  • Go語言中的iota關(guān)鍵字的使用

    Go語言中的iota關(guān)鍵字的使用

    這篇文章主要介紹了Go語言中的iota關(guān)鍵字的使用的相關(guān)資料,需要的朋友可以參考下
    2023-08-08
  • Go底層channel實現(xiàn)原理及示例詳解

    Go底層channel實現(xiàn)原理及示例詳解

    這篇文章主要介紹了Go底層channel實現(xiàn)原理及示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • Golang中函數(shù)的使用方法詳解

    Golang中函數(shù)的使用方法詳解

    這篇文章主要詳細(xì)介紹了Golang中函數(shù)的使用方法,文中有詳細(xì)的示例代碼,對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2023-05-05
  • Go語言中的time.Tick 函數(shù)用法解讀

    Go語言中的time.Tick 函數(shù)用法解讀

    Go1.23+中time.Tick自動回收資源,適配長期定時任務(wù);NewTicker需手動Stop(),適合需精細(xì)控制的場景,簡單任務(wù)推薦Tick,復(fù)雜需求或舊版本仍建議NewTicker+defer Stop()
    2025-07-07

最新評論

盐边县| 通辽市| 湛江市| 江安县| 北京市| 江安县| 葫芦岛市| 泰兴市| 顺平县| 雷山县| 仙居县| 南皮县| 汕尾市| 广宗县| 阳新县| 石楼县| 马山县| 新源县| 新邵县| 洪雅县| 焉耆| 黔西县| 齐齐哈尔市| 和林格尔县| 依安县| 中方县| 雷波县| 通道| 沙河市| 十堰市| 巴彦县| 黔东| 绥宁县| 白城市| 敦煌市| 井研县| 科技| 石嘴山市| 库伦旗| 法库县| 南和县|