【问题标题】:Go socket : too many open filesGo socket:打开的文件太多
【发布时间】:2015-07-11 02:35:43
【问题描述】:

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

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 可以完成这项工作。

谢谢!

【问题讨论】:

  • 我在 ubuntu 14.04 和 go1.5beta1 下运行这个
  • @BravadaZadada 该请求是针对同一主机的。在一个函数里面。谢谢
  • 不,只有这一个请求。谢谢

标签: sockets http go


【解决方案1】:

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

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 的原因是为了确保在稍后有一堆处理可能返回或出现错误时关闭主体。

【讨论】:

  • 谢谢!我在一个函数中调用这个调用。最好的方法是什么?是否也应该在其他调用周围传递客户端指针?我试图重新启动 api 调用并在一个函数调用中将其销毁。
  • 已更新示例。你不应该在这里需要任何特别的东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-09
  • 2011-07-18
相关资源
最近更新 更多