search.png
关于我
menu.png
go http server 不同情况下退出的进程返回状态码

ctrl+c 中断

结果是1

//go test -run Test1
// Ctrl+c
//echo %errorlevel% => 1 中断
func Test1(t *testing.T) {

    server := &http.Server{
        Addr: ":8080",
        Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            fmt.Println(r)
            _, _ = w.Write([]byte("OK"))
        }),
        ReadTimeout:  10 * time.Second,
        WriteTimeout: 10 * time.Second,
        // 1 MB
        MaxHeaderBytes: 1 << 20,
    }

    go func() {
        err := server.ListenAndServe()
        if err != nil {
            fmt.Println(err)
        }
    }()

    gracefulExitWeb(server)
}

// 优雅退出的过程
// 1)关闭所有的监听
// 2)后关闭所有的空闲连接
// 3)无限期等待活动的连接处理完毕转为空闲,并关闭
// 如果提供了带有超时的Context,将在服务关闭前返回 Context的超时错误
func gracefulExitWeb(server *http.Server) {
    ch := make(chan os.Signal)
    signal.Notify(ch, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGINT)
    sig := <-ch

    fmt.Println("got a signal", sig)
    now := time.Now()

    cxt, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()
    err := server.Shutdown(cxt)
    if err != nil {
        fmt.Println("err", err)
    }

    // 看看实际退出所耗费的时间
    fmt.Println("------exited--------", time.Since(now))
}

自动退出

结果是0

//go test -run Test2
// Ctrl+c
//echo %errorlevel% => 0 自动退出
func Test2(t *testing.T) {

    server := &http.Server{
        Addr: ":8080",
        Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            fmt.Println(r)
            _, _ = w.Write([]byte("OK"))
        }),
        ReadTimeout:  10 * time.Second,
        WriteTimeout: 10 * time.Second,
        // 1 MB
        MaxHeaderBytes: 1 << 20,
    }

    go func() {
        err := server.ListenAndServe()
        if err != nil {
            fmt.Println(err)
        }
    }()

    time.Sleep(3 * time.Second)
    err := server.Shutdown(context.Background())
    if err != nil {
        fmt.Println(err)
    }
}

panic 退出

结果是1

//go test -run Test3
// Ctrl+c
//echo %errorlevel% => 1 panic退出
func Test3(t *testing.T) {

    server := &http.Server{
        Addr: ":8080",
        Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            fmt.Println(r)
            _, _ = w.Write([]byte("OK"))
        }),
        ReadTimeout:  10 * time.Second,
        WriteTimeout: 10 * time.Second,
        // 1 MB
        MaxHeaderBytes: 1 << 20,
    }

    go func() {
        err := server.ListenAndServe()
        if err != nil {
            fmt.Println(err)
        }
    }()

    time.Sleep(3 * time.Second)
    panic("this is panic")
}

版权声明

知识共享许可协议 本文章由作者“衡于墨”创作,转载请注明出处,未经允许禁止用于商业用途

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。
发布时间:2022年06月25日 09:47:32

评论区#

还没有评论哦,期待您的评论!

关闭特效