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

詳解如何熱重啟golang服務(wù)器

 更新時(shí)間:2018年08月16日 14:13:20   作者:black_ox  
這篇文章主要介紹了詳解如何熱重啟golang服務(wù)器,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

服務(wù)端代碼經(jīng)常需要升級(jí),對(duì)于線上系統(tǒng)的升級(jí)常用的做法是,通過前端的負(fù)載均衡(如nginx)來保證升級(jí)時(shí)至少有一個(gè)服務(wù)可用,依次(灰度)升級(jí)。

而另一種更方便的方法是在應(yīng)用上做熱重啟,直接升級(jí)應(yīng)用而不停服務(wù)。

原理

熱重啟的原理非常簡(jiǎn)單,但是涉及到一些系統(tǒng)調(diào)用以及父子進(jìn)程之間文件句柄的傳遞等等細(xì)節(jié)比較多。
處理過程分為以下幾個(gè)步驟:

  • 監(jiān)聽信號(hào)(USR2)
  • 收到信號(hào)時(shí)fork子進(jìn)程(使用相同的啟動(dòng)命令),將服務(wù)監(jiān)聽的socket文件描述符傳遞給子進(jìn)程
  • 子進(jìn)程監(jiān)聽父進(jìn)程的socket,這個(gè)時(shí)候父進(jìn)程和子進(jìn)程都可以接收請(qǐng)求
  • 子進(jìn)程啟動(dòng)成功之后,父進(jìn)程停止接收新的連接,等待舊連接處理完成(或超時(shí))
  • 父進(jìn)程退出,升級(jí)完成

細(xì)節(jié)

  • 父進(jìn)程將socket文件描述符傳遞給子進(jìn)程可以通過命令行,或者環(huán)境變量等
  • 子進(jìn)程啟動(dòng)時(shí)使用和父進(jìn)程一樣的命令行,對(duì)于golang來說用更新的可執(zhí)行程序覆蓋舊程序
  • server.Shutdown()優(yōu)雅關(guān)閉方法是go1.8的新特性
  • server.Serve(l)方法在Shutdown時(shí)立即返回,Shutdown方法則阻塞至context完成,所以Shutdown的方法要寫在主goroutine中

代碼

package main
import (
  "context"
  "errors"
  "flag"
  "log"
  "net"
  "net/http"
  "os"
  "os/exec"
  "os/signal"
  "syscall"
  "time"
)
 
var (
  server  *http.Server
  listener net.Listener
  graceful = flag.Bool("graceful", false, "listen on fd open 3 (internal use only)")
)
 
func handler(w http.ResponseWriter, r *http.Request) {
  time.Sleep(20 * time.Second)
  w.Write([]byte("hello world233333!!!!"))
}
 
func main() {
  flag.Parse()
 
  http.HandleFunc("/hello", handler)
  server = &http.Server{Addr: ":9999"}
 
  var err error
  if *graceful {
    log.Print("main: Listening to existing file descriptor 3.")
    // cmd.ExtraFiles: If non-nil, entry i becomes file descriptor 3+i.
    // when we put socket FD at the first entry, it will always be 3(0+3)
    f := os.NewFile(3, "")
    listener, err = net.FileListener(f)
  } else {
    log.Print("main: Listening on a new file descriptor.")
    listener, err = net.Listen("tcp", server.Addr)
  }
 
  if err != nil {
    log.Fatalf("listener error: %v", err)
  }
 
  go func() {
    // server.Shutdown() stops Serve() immediately, thus server.Serve() should not be in main goroutine
    err = server.Serve(listener)
    log.Printf("server.Serve err: %v\n", err)
  }()
  signalHandler()
  log.Printf("signal end")
}
 
func reload() error {
  tl, ok := listener.(*net.TCPListener)
  if !ok {
    return errors.New("listener is not tcp listener")
  }
 
  f, err := tl.File()
  if err != nil {
    return err
  }
 
  args := []string{"-graceful"}
  cmd := exec.Command(os.Args[0], args...)
  cmd.Stdout = os.Stdout
  cmd.Stderr = os.Stderr
  // put socket FD at the first entry
  cmd.ExtraFiles = []*os.File{f}
  return cmd.Start()
}
 
func signalHandler() {
  ch := make(chan os.Signal, 1)
  signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM, syscall.SIGUSR2)
  for {
    sig := <-ch
    log.Printf("signal: %v", sig)
 
    // timeout context for shutdown
    ctx, _ := context.WithTimeout(context.Background(), 20*time.Second)
    switch sig {
    case syscall.SIGINT, syscall.SIGTERM:
      // stop
      log.Printf("stop")
      signal.Stop(ch)
      server.Shutdown(ctx)
      log.Printf("graceful shutdown")
      return
    case syscall.SIGUSR2:
      // reload
      log.Printf("reload")
      err := reload()
      if err != nil {
        log.Fatalf("graceful restart error: %v", err)
      }
      server.Shutdown(ctx)
      log.Printf("graceful reload")
      return
    }
  }
}

references

Graceful Restart in Golang

facebookgo/grace

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Go語(yǔ)言利用ffmpeg轉(zhuǎn)hls實(shí)現(xiàn)簡(jiǎn)單視頻直播

    Go語(yǔ)言利用ffmpeg轉(zhuǎn)hls實(shí)現(xiàn)簡(jiǎn)單視頻直播

    這篇文章主要為大家介紹了Go語(yǔ)言利用ffmpeg轉(zhuǎn)hls實(shí)現(xiàn)簡(jiǎn)單視頻直播,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-04-04
  • golang類型斷言的實(shí)現(xiàn)示例

    golang類型斷言的實(shí)現(xiàn)示例

    在Go語(yǔ)言中,類型斷言用于從接口類型獲取其具體類型的值,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-10-10
  • go等待一組協(xié)程結(jié)束的操作方式

    go等待一組協(xié)程結(jié)束的操作方式

    這篇文章主要介紹了go等待一組協(xié)程結(jié)束的操作方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • 淺談Golang中創(chuàng)建一個(gè)簡(jiǎn)單的服務(wù)器的方法

    淺談Golang中創(chuàng)建一個(gè)簡(jiǎn)單的服務(wù)器的方法

    這篇文章主要介紹了淺談Golang中創(chuàng)建一個(gè)簡(jiǎn)單的服務(wù)器的方法,golang中的net/http包對(duì)網(wǎng)絡(luò)的支持非常好,這樣會(huì)讓我們比較容易的建立起一個(gè)相對(duì)簡(jiǎn)單的服務(wù)器,有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • go內(nèi)存緩存BigCache使用入門詳解

    go內(nèi)存緩存BigCache使用入門詳解

    這篇文章主要為大家介紹了go內(nèi)存緩存BigCache使用入門詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • Golang多線程爬蟲高效抓取大量數(shù)據(jù)的利器

    Golang多線程爬蟲高效抓取大量數(shù)據(jù)的利器

    Golang多線程爬蟲是一種高效抓取大量數(shù)據(jù)的利器。Golang語(yǔ)言天生支持并發(fā)和多線程,可以輕松實(shí)現(xiàn)多線程爬蟲的開發(fā)。通過使用Golang的協(xié)程和通道,可以實(shí)現(xiàn)爬蟲的高效并發(fā)抓取、數(shù)據(jù)處理和存儲(chǔ)
    2023-05-05
  • 基于Go語(yǔ)言實(shí)現(xiàn)猜謎游戲

    基于Go語(yǔ)言實(shí)現(xiàn)猜謎游戲

    這篇文章主要為大家詳細(xì)介紹了如何基于Go語(yǔ)言實(shí)現(xiàn)猜謎游戲,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)
    2023-09-09
  • go?doudou開發(fā)單體RESTful服務(wù)快速上手教程

    go?doudou開發(fā)單體RESTful服務(wù)快速上手教程

    這篇文章主要為大家介紹了go?doudou開發(fā)單體RESTful服務(wù)快速上手教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • 深入Go goroutine理解

    深入Go goroutine理解

    這篇文章主要介紹了深入Go goroutine理解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-02-02
  • golang fmt格式“占位符”的實(shí)例用法詳解

    golang fmt格式“占位符”的實(shí)例用法詳解

    在本篇文章里小編給大家整理的是一篇關(guān)于golang fmt格式“占位符”的實(shí)例用法詳解內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。
    2021-07-07

最新評(píng)論

台中县| 三河市| 巧家县| 开平市| 黔南| 海兴县| 武邑县| 曲阳县| 周至县| 沙田区| 兴安县| 云霄县| 高淳县| 山阳县| 吉木萨尔县| 宣武区| 庆阳市| 西昌市| 天长市| 武功县| 新兴县| 广平县| 封丘县| 克拉玛依市| 龙门县| 繁峙县| 永顺县| 疏勒县| 吴川市| 甘泉县| 江源县| 临颍县| 合作市| 罗田县| 岑巩县| 临安市| 西乡县| 化德县| 黑水县| 千阳县| 隆德县|