不管是否使用 Resp 的内容都需要手动关闭,否则会导致进程打开的 fd
一直变多,最终系统杀掉进程,报错类似:
http: Accept error: accept tcp [::]:4200: accept4: too many open files; retrying in 1s
HTTP连接的功能由3个goroutine协同实现,一个主goroutine,一个readLoop,一个writeLoop,后两个goroutine生命周期和连接一致。如果body没有被关闭,那么这次http事务就没有完成,会造成readLoop和 writeLoop 两个goroutine的阻塞,除非连接因超时终止了,否则相关资源无法被回收。
// 正确示例
func main() {
resp, err := http.Get("<http://www.baidu.com>")
// 关闭 resp.Body 的正确姿势
if resp != nil {
defer resp.Body.Close()
}
checkError(err)
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
checkError(err)
fmt.Println(string(body))
}