我在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)
}
}
有关文件句柄数或最大连接数的问题?
答案 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()
中说。 net.Conn
想要拥有的FileDescriptors。这个
限制只能在操作系统级别上消除。