最近碰到群裡網友問如果檢查網路連接的Timeout,聯想最近看到的另一個問題, 在這篇文章統一記錄一下。
如果檢查一個網路錯誤是Timeout導致的?
自 Go 1.6開始, 所有的逾時導致的網路錯誤都可以通過net.Error
的Timeout()
方法檢查。
123 |
if err, ok := err.(net.Error); ok && err.Timeout() { ……} |
更早版本的Go並沒有專門的檢查Timeout方法。
可以參考: https://stackoverflow.com/questions/23494950/specifically-check-for-timeout-error
產品中一定不要使用預設的http.Get
如果你覺得方便,直接使用http.Get
或者類似的方法發送請求,可能會導致一些問題, 因為這預設是使用DefaultClient
作為client:
- 多goroutine共用,這意味著在別處對
DefaultClient
的改動會影響你當前的使用
- 未設定connection timeout和 read/write timeout
- 預設的idle connection等設定可能不滿足你的需求
一個具體的使用預設的client導致的問題可以參考 Don’t use Go’s default HTTP client (in production)。
所以Go開發過程中最好使用自己定製的Client:
1234567891011121314151617181920212223 |
var timeout = time.Duration(2 * time.Second)func dialTimeout(network, addr string) (net.Conn, error) { return net.DialTimeout(network, addr, timeout)}func main() { transport := http.Transport{ Dial: dialTimeout, Proxy: ..., MaxIdleConns: ..., MaxIdleConnsPerHost: ..., IdleConnTimeout: ..., ResponseHeaderTimeout: ..., DisableCompression:..., } client := http.Client{ Transport: &transport, } resp, err := client.Get("http://some.url")} |
酌情設定Transport
的參數。