从官方文档https://golang.org/pkg/net/http/#Client.Do来看,似乎RoundTripper 可能无法为下一个" keep-alive"重新使用TCP连接。请求Body是否未关闭且未完全阅读。这可能的内容是什么?
从我看到的内容当读取整个Body时,不一定需要调用Close。那么连接重用的必要条件是什么?
代码片段(注释为defer resp.Body.Close()
),它在循环中创建多个连接,并通过netstat分析它,似乎所有连接都使用相同的TCP连接:
for nextPage != "" {
req, err := http.NewRequest("GET", nextPage, nil)
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", *token))
if err != nil {
panic(err)
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
// defer resp.Body.Close()
result := []*User{}
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
panic(err)
}
nextPage = getNextPage(resp.Header.Get("Link"))
}
答案 0 :(得分:0)
文件没有说Don't call Close() for keep-alive
。只需说if you want to re-use connection, you MUST call Close() and fully read.
答案 1 :(得分:0)
您只能依靠文档中的内容。在某些情况下(转换版本,操作系统,体系结构,响应内容长度等),可能重用连接而不完全读取它,或者它可能不会。如果你想确保连接将被重用,你必须完全读取正文并关闭它。
我通常写一个快速帮手:
func cleanUpRequest(req *http.Request) {
if req != nil && req.Body != nil {
io.Copy(ioutil.Discard, req.Body)
req.Body.Close()
}
}
即使在错误检查之前,这对defer
也是安全的。