golang中的web服务平滑重启

新进来的请求怎么办?

  • fork一个子进程,继承父进程的监听socket
  • 子进程启动成功之后,接收新的连接
  • 父进程停止接收新的连接,等已有的请求处理完毕,退出
  • 优雅重启成功

平滑升级

子进程如何继承父进程的文件句柄?

  • 通过os.Cmd对象中的ExtraFiles参数进行传递

子进程如何继承父进程的文件句柄

  • 通过os.Cmd对象中的ExtraFiles参数进行传递
  • 文件句柄继承实例分析

web服务器平滑升级

  • 使用go1.8版本的shutdown方法进行优雅关闭
  • 使用socket继承实现,子进程接管父进程的监听socket

文件句柄继承实例分析

package main

import (
   "flag"
   "fmt"
   "os"
   "os/exec"
   "time"
)

var (
   child *bool
)

func init() {
   child = flag.Bool("child", false, "继承于父进程(internal use only)")
   flag.Parse()
}

func readFromParent() {
   //fd = 0,标准输出
   //fd = 1,标准输入
   //fd = 2,标准错误输出
   //fd = 3, ==> ExtraFiles[0]
   //fd = 4, ==> ExtraFiles[1]

   //第一个参数文件句柄的下标,就是ExtraFiles[0], 第二个参数名字可以随便取
   f := os.NewFile(3, "")
   count := 0
   for {
      //格式化字符串
      str := fmt.Sprintf("hello, i'child process, write: %d line \n", count)
      count++
      //写入到这个文件
      _, err := f.WriteString(str)
      if err != nil {
         fmt.Printf("write string failed, err: %v\n", err)
         time.Sleep(time.Second)
         continue
      }
      //每一秒写下文件
      time.Sleep(time.Second)
   }
}

//启动子进程
func startChild(file *os.File) {
   args := []string{"-child"}
   //os.Args[0]是文件路径,带上-child选项
   cmd := exec.Command(os.Args[0], args...)
   cmd.Stdout = os.Stdout
   cmd.Stderr = os.Stderr
   //放socket fd在第一个entry,只要把父进程传递过来的放在这里
   cmd.ExtraFiles = []*os.File{file}
   //到main函数
   err := cmd.Start()

   if err != nil {
      fmt.Printf("start child failed, err: %v\n", err.Error())
      return
   }
}

func main() {
   //表示已经是一个子进程了
   if child != nil && *child == true {
      fmt.Printf("继承于父进程的文件句柄\n")
      //子进程
      readFromParent()
      return
   }

   //父进程的逻辑,打开文件句柄
   file, err := os.OpenFile("./test.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0755)
   if err != nil {
      fmt.Printf("open file failed, err:%v\n", err)
      return
   }

   //启动一个子进程,把文件句柄给子进程
   startChild(file)
   fmt.Println("父进程退出")
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

盼盼编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值