在 Go 專案為 HTTP 服務端和客戶端設置超時時間

前言

在使用 Go 撰寫 HTTP 服務端或客戶端的時候,需要設置超時時間,避免響應或請求過久,導致網路故障或程序當機。

服務端

在服務端,http.Server 有兩個設置超時的欄位。ReadTimeout 的時間計算是從連接被接受到 request body 完全被讀取。WriteTimeout 的時間計算是從 request header 的讀取結束開始,到 response write 結束為止。

1
2
3
4
5
srv := &http.Server{  
ReadTimeout: 5 * time.Second,
WriteTimeout: 10 * time.Second,
}
log.Println(srv.ListenAndServe())

客戶端

在客戶端,http.Client 有一個簡單的 Timeout 欄位可以設置超時。它的時間計算包括從連接(Dial)到讀取完 response body 為止。

1
2
3
4
c := &http.Client{  
Timeout: 15 * time.Second,
}
resp, err := c.Get()

其他還有以下超時控制:

  • net.Dialer.Timeout:限制建立 TCP 連接的時間。
  • http.Transport.TLSHandshakeTimeout:限制 TLS 握手的時間。
  • http.Transport.ResponseHeaderTimeout:限制讀取 response header 的時間。
  • http.Transport.ExpectContinueTimeout:限制 client 在發送包含 Expect: 100-continue 的 header 到收到繼續發送 body 的 response 之間的等待時間。
1
2
3
4
5
6
7
8
9
10
11
c := &http.Client{
Transport: &Transport{
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).DialContext,
TLSHandshakeTimeout: 10 * time.Second,
ResponseHeaderTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
}
}

參考資料