golang中的web服务平滑重启
生活随笔
收集整理的這篇文章主要介紹了
golang中的web服务平滑重启
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
新進來的請求怎么辦?
- fork一個子進程,繼承父進程的監聽socket
- 子進程啟動成功之后,接收新的連接
- 父進程停止接收新的連接,等已有的請求處理完畢,退出
- 優雅重啟成功
平滑升級
子進程如何繼承父進程的文件句柄?
- 通過os.Cmd對象中的ExtraFiles參數進行傳遞
子進程如何繼承父進程的文件句柄
- 通過os.Cmd對象中的ExtraFiles參數進行傳遞
- 文件句柄繼承實例分析
web服務器平滑升級
- 使用go1.8版本的shutdown方法進行優雅關閉
- 使用socket繼承實現,子進程接管父進程的監聽socket
文件句柄繼承實例分析
package mainimport ("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 := 0for {//格式化字符串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.Stdoutcmd.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("父進程退出") }總結
以上是生活随笔為你收集整理的golang中的web服务平滑重启的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: golang中的优雅中止
- 下一篇: golang中的goredis