当前位置: 首页 > 工具软件 > gohttp > 使用案例 >

使用 go http 包的注意点 (超时 和 accept4: too many open files; retrying in 1s)

钱青青
2023-12-01

使用 go http 包的注意点

很多人最开始使用go的http包的时候,都会找一个示例,以下面代码为例

    res, err := http.Get(url)
    if err != nil {
        return false
    }
    return res.StatusCode == http.StatusOK

这里面其实有两个错误。

问题1 超时

我们实际去看 Get的实现会发现,Get使用了包内的变量,他是全局的。

//Clients are safe for concurrent use by multiple goroutines.

var DefaultClient = &Client{}

func Get(url string) (resp *Response, err error) {
	return DefaultClient.Get(url)
}

以上三段在不同行,放一起方便看。
首先他是并发安全的,那就大胆的用(废话…)
其次需要注意的是,client是没有初始化超时的,如果使用这个示例去写生产代码,99%的时候都是很正常的。一旦网络抖动,那么就会导致这一个连接一直保持下去。(接下来会发生什么大家都懂了吧,连接数打满,内存持续上升)

并且由于它是单例的(包变量),垃圾收集器不会尝试去清理他,会有空闲的流一直保持着。

所以最好设置超时,最简单的办法就是在项目启动的init设置全局(项目级别)默认的超时

http.DefaultClient.Timeout = time.Minute

其次也可以自己创建新的client去用

client := http.Client{ Timeout: time.Second * 10 }

问题2 没有关闭流

遇到这类错误
accept4: too many open files; retrying in 1s
可能是缺少了

defer res.Body.Close()

具体defer知识点就不展开咯 ?

 类似资料: