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/