您好,我正在创建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 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
})