Goroutine在到达http服务器超时后不会停止

问题描述 投票:0回答:1

您好,我正在创建Golang http服务器,但是服务器超时有问题。

这里是代码:

func main() {
    mux := http.NewServeMux()

    mux.HandleFunc("/check", func(w http.ResponseWriter, r *http.Request) {
        time.Sleep(5 * time.Second)
        log.Print("after 5 seconds")

        a := 0
        for i := 0; i < 1000000; i++ {
            a++
        }

        time.Sleep(5 * time.Second)
        log.Print("after 10 seconds")

        fmt.Fprint(w, "Hello World")
        return
    })

    server := &http.Server{
        Addr:              ":8088",
        Handler:           mux,
        ReadHeaderTimeout: 5 * time.Second,
        ReadTimeout:       5 * time.Second,
        WriteTimeout:      5 * time.Second,
    }
    log.Fatal(server.ListenAndServe())
}

结果:

2020/02/29 09:48:23 after 5 seconds
2020/02/29 09:48:28 after 10 seconds

达到5秒超时后,goroutine仍在处理程序函数中执行代码。

到达超时后如何停止goroutine执行?

go timeout goroutine
1个回答
0
投票
请参阅go doc以了解其预期用途:

// ReadTimeout is the maximum duration for reading the entire // request, including the body. // // Because ReadTimeout does not let Handlers make per-request // decisions on each request body's acceptable deadline or // upload rate, most users will prefer to use // ReadHeaderTimeout. It is valid to use them both. ReadTimeout time.Duration // ReadHeaderTimeout is the amount of time allowed to read // request headers. The connection's read deadline is reset // after reading the headers and the Handler can decide what // is considered too slow for the body. If ReadHeaderTimeout // is zero, the value of ReadTimeout is used. If both are // zero, there is no timeout. ReadHeaderTimeout time.Duration // WriteTimeout is the maximum duration before timing out // writes of the response. It is reset whenever a new // request's header is read. Like ReadTimeout, it does not // let Handlers make decisions on a per-request basis. WriteTimeout time.Duration

请参阅以下有关限制HandlerFunc时间的潜在方法,但请注意以下内容存在问题,即即使HandleFunc已返回,但go例程仍将运行整个10秒钟。 。解决方法请参见How to stop a goroutine

mux.HandleFunc("/check", func(w http.ResponseWriter, r *http.Request) {
        handleDone := make(chan bool)
        go func() {
                time.Sleep(5 * time.Second)
                log.Print("after 5 seconds")

                a := 0
                for i := 0; i < 1000000; i++ {
                        a++
                }

                time.Sleep(5 * time.Second)
                log.Print("after 10 seconds")

                fmt.Fprint(w, "Hello World")
        }()

        select {
        case <-time.After(5 * time.Second):
                log.Print("timed out")
                w.WriteHeader(http.StatusRequestTimeout)
        case <-handleDone:
        }
        return
})

© www.soinside.com 2019 - 2024. All rights reserved.