是ioutil.ReadAll阻止我的服务器?

时间:2014-09-17 23:29:19

标签: asynchronous go

我正在尝试使用net/http包在Go中编写服务器。我只有一条路线,而且非常简单。它从S3下载文件并将其返回给客户端:

response, err := http.Get("some S3 url")
if err != nil {
    return
}
body, err := ioutil.ReadAll(response.Body)
w.Write(body)

自己下载网址大约需要0.25秒。所以我启动这个服务器并发送250个请求/秒。最初我在0.25秒内收到回复。但是这个数字一直在上升,直到它开始需要45秒才能得到响应。我在40核心机器上运行它,GOMAXPROCS=40。我开始想知道是否以某种方式并行发生了下载。

但如果我注释掉这一行:

body, err := ioutil.ReadAll(response.Body)

只返回一些相同长度的垃圾数据,突然我的服务器在0.25秒内始终响应。删除ReadAll后为什么会更快?

1 个答案:

答案 0 :(得分:2)

几乎没有想到的事情:

  1. 您没有关闭response.Body,服务器用完了FD。
  2. 垃圾收集器速度很慢,而且您使用ReadAll来读取这么多文件时内存不足。
  3. 你因为#1而窒息网络。
  4. 尝试这样的事情,看看是否有帮助:

    response, err := http.Get("some S3 url")
    if err != nil {
        return
    }
    defer response.Body.Close()
    _, err := io.Copy(w, response.Body)