Golang HTTP 并发请求 POST EOF

9

我正在使用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)
    }
}

问题是关于文件句柄数还是最大连接数的?

你正在使用哪个操作系统? - fredrik
你可能想修改你的并发性,这样你就有了一组固定的goroutine来协作完成一定量的工作。目前,你正在扇出等于总工作量的goroutine数量,这可能有点过度。请参阅Worker Pools: https://gobyexample.com/worker-pools - dyoo
我将测试我的服务器的稳定性。因此,当服务器在高压下运行时,我希望分析数据。操作系统是CentOS。 - nemo
我正在使用Web框架beego。它有问题吗? - nemo
错误代码为 "Post http://xvz.myserver.com:9000/path/create: EOF"。 - nemo
3个回答

20

在我看来,你可能遇到了这个答案中描述的问题。基本上,Go的http客户端会尝试重用连接,除非你已经明确指示它不应该这样做,要么在你设置Client实例使用的Transport中明确指示,要么在请求本身中明确指示:

request.Close = true

当服务器在响应中没有使用Connection: close头来指示时,如果连接被关闭,这将成为一个问题。 net.http 代码假定连接仍然打开,因此下一个尝试使用连接的请求会遇到之前连接被关闭时出现的EOF错误。

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


1
  • 首先,在循环内部的DoCreate()中每次实例化新客户端client := &http.Client{...是为了什么?客户端可以被重复使用,甚至可以并发使用,因此您可以更全局地构造它,比如在main()中。
  • 然后,对我来说,这样的错误看起来像是由RoundTrip产生的,所以可能是由连接或服务器端引起的。您能否通过模拟服务器进行测试?
  • 最后,如果所有这些都没有帮助,那么是的,一些系统对每个net.Conn想要拥有自己的打开文件描述符的数量有限制。这种限制只能在操作系统级别上消除。

1
谢谢你的帮助,你是对的,“客户端甚至可以同时重复使用”。 - nemo

1
EOF通常是由于服务器没有返回完整的标头(包括两个),或者在标头完成之前连接被关闭。更可能的是,您正在使用并发请求过载服务器,尽管您仍应确保本地资源足够处理您正在进行的并发请求。如果num足够大,您将耗尽某些资源。
虽然该错误并不真正具有描述性,但它并不比其他请求错误更值得担心。这是一个错误条件,像处理其他错误一样处理它。如果您想确定,您可能需要捕获导致EOF的连接的数据包。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接