Server Timeouts
http server有两个时间选项可设置
srv := &http.Server{
ReadTimeout: 5 * time.Second,
WriteTimeout: 10 * time.Second,
}
log.Println(srv.ListenAndServe())
图中的http.TimeoutHandler不般不控制时间, 是项目handler层开始到输出结果的时间。
Client Timeouts
设置 http.Client.Timeout
c := &http.Client{
Timeout: 15 * time.Second,
}
resp, err := c.Get("https://xxx/")
设置net.Dialer.Timeout 和 http.Transport Timeout
c := &http.Client{
Transport: &http.Transport{
Dial: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).Dial,
TLSHandshakeTimeout: 10 * time.Second,
ResponseHeaderTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
}
}
每个request 独立设置Timeout
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
req, err := http.NewRequestWithContext(ctx, "GET", URL, nil)
刷新Timeout,不断延后Timeout的控制方法
package main
import (
"io"
"io/ioutil"
"log"
"net/http"
"time"
)
func main() {
c := make(chan struct{})
timer := time.AfterFunc(5*time.Second, func() {
close(c)
})
// Serve 256 bytes every second.
req, err := http.NewRequest("GET", "http://httpbin.org/range/2048?duration=8&chunk_size=256", nil)
if err != nil {
log.Fatal(err)
}
req.Cancel = c
log.Println("Sending request...")
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
log.Println("Reading body...")
for {
timer.Reset(2 * time.Second)
// Try instead: timer.Reset(50 * time.Millisecond)
_, err = io.CopyN(ioutil.Discard, resp.Body, 256)
if err == io.EOF {
break
} else if err != nil {
log.Fatal(err)
}
}
}
原文连接
有兴趣可以读一下原文, 内容要详细很多。 本文中是摘录了 图片,做简单的说明。
The complete guide to Go net/http timeouts
https://blog.cloudflare.com/the-complete-guide-to-golang-net-http-timeouts/