最近碰到群里网友问如果检查网络连接的 Timeout, 联想最近看到的另一个问题, 在这篇文章统一记录一下
如果检查一个网络错误是 Timeout 导致的?
自 Go 1.6 开始, 所有的超时导致的网络错误都可以通过 net.Error 的 Timeout() 方法检查
- 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 导致的问题可以参考 Dont use Gos default HTTP client (in production)
所以 Go 开发过程中最好使用自己定制的 Client:
- 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 的参数
来源: http://www.tuicool.com/articles/ieiiYby