Golang HTTP并发请求POST EOF

时间:2015-01-20 13:05:50

标签: http web go

我在Go中运行一个小客户端。我们此刻收到了一些误报,似乎在client.Do()num>=1000返回了一个EOF错误。

这是我的代码的本质:

func DoCreate(js string, cli *http.Client) {

    url2 := "http://xvz.myserver.com:9000/path/create"

    postBytesReader := bytes.NewReader([]byte(js))
    request, _ := http.NewRequest("POST", url2, postBytesReader)

    resp, err := cli.Do(request)
    if err != nil {
        fmt.Println(err) // Post http://xvz.myserver.com:9000/path/create: EOF 
        return
    }
    body, _ := ioutil.ReadAll(resp.Body)
    fmt.Println(string(body))

    defer resp.Body.Close()
}

func main() {
    client := &http.Client{
        CheckRedirect: nil,
    }

    for i := 0; i < num; i++ {
        var pq CreateReqInfo
        pq.Uid = strconv.Itoa(bid + i)
        petstr, _ := json.Marshal(pq)
        go DoCreate(string(petstr), client)
    }
}

有关文件句柄数或最大连接数的问题?

3 个答案:

答案 0 :(得分:3)

我认为您可能遇到this answer中描述的问题。基本上,Go http客户端将尝试重用连接,除非您明确指出它不应该在您设置Transport实例的Client中使用,也不应该在请求本身上:

request.Close = true

当另一端的服务器关闭连接而没有在响应中使用Connection: close标头指示时,这就成了问题。 net.http代码假定连接仍处于打开状态,因此下一次尝试使用连接的请求会在另一次关闭的连接中遇到EOF

您需要检查第1000个请求周围连接上发生的情况。接收服务器是否设置为限制每个客户端的连接数?您的代码是否正在运行连接超时?在任何一种情况下,如果发生这种情况,服务器会以Go Client代码无法预测的方式关闭连接,那么您将遇到EOF

答案 1 :(得分:1)

EOF通常来自不返回完整标头的服务器(包括CRLF),或者在标头完成之前关闭连接。使用并发请求重载服务器的可能性更大,但您仍应确保本地有足够的资源来处理您正在进行的并发请求的数量。如果num足够大,那么你就会用完一些东西。

虽然错误并不是真正描述性的,但是除了任何其他请求错误之外,没有什么可担心的。这是一个错误的情况,并像处理任何其他人一样处理它。如果您想确切知道,您可能必须获取导致EOF的连接的数据包捕获。

答案 2 :(得分:0)

  • 首先,每次client := &http.Client{...在循环内部DoCreate()内实例化新客户端是什么?客户可以 甚至可以同时重复使用,因此您可以在全球范围内构建它, 我觉得在main()中说。
  • 然后对我来说这样的错误看起来像 由RoundTrip生成,所以通过连接,所以可能来自服务器站点。你能 用mocking服务器测试?
  • 最后,如果一切都没有用,那么 是的,有些系统对打开的数量有限制 每个net.Conn想要拥有的FileDescriptors。这个 限制只能在操作系统级别上消除。