Go socket:打开的文件太多了

时间:2015-07-10 15:25:17

标签: sockets http go

当我从以下代码发送请求时:

req, err := http.NewRequest("GET", "my_target:", nil)
if err != nil {
    panic(err)
}
req.Close = true
client := http.DefaultClient
resp, err := client.Do(req)
if err != nil {
    panic(err)
}
defer resp.Body.Close()

在每分钟发送平均10个请求几个小时后,我收到此错误:

socket: too many open files

如何找到此问题的原因?

我没有关闭http.Request吗?

我以为req.Close = true做了那件事。

谢谢!

1 个答案:

答案 0 :(得分:7)

为什么要推迟收盘?你真的在读这个身体吗?

defer resp.Body.Close()

在执行另一个Get之前,您是否实际从当前函数返回?如果没有,则defer将永远不会执行,并且您永远不会释放此连接以供重复使用。

req.Close = true也是一个不寻常的选择。这也可以防止连接重用,这是您可能想要的而不是禁止的。这并不会自动关闭您的请求。它会强制服务器立即关闭连接,否则您将重复使用该连接。在你关闭它之前,你会保持开放。

通常对于像这里一样的简单GET请求,我会这样做:

resp, err := http.Get("...")
if err != nil {
    panic(err) // panic seems harsh, usually you'd just return the error. But either way...
}
resp.Body.Close()

这里不需要特殊的客户。只需使用默认值。只要你确保关闭响应体,它就会处理剩下的事情。如果您要立即关闭身体,则无需使用defer使事情复杂化。 defer的原因是为了确保在以后有一堆处理可能会在错误时返回或发生混乱时关闭正文。