8

I'm running a small client in Go. We're getting a number of false alarms at the moment, which seem to come down to client.Do() returning an EOF error when num>=1000.

This is the essence of my code:

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)
    }
}

Is problem about number of file handles or max connections?

tshepang
  • 12,111
  • 21
  • 91
  • 136
nemo
  • 115
  • 2
  • 2
  • 5
  • What OS are you running on? – fredrik Jan 21 '15 at 00:30
  • You may want to modify your concurrency such that you have a fixed set of goroutines that cooperate to finish an amount of work. At the moment, you're fanning out a number of goroutines equal to the total amount of work, which might be a bit overkill. See Worker Pools: https://gobyexample.com/worker-pools – dyoo Jan 21 '15 at 01:01
  • i will test the Stability of my server . so i want to Analysis of data when the server running under high pressure. the os is centos~~ – nemo Jan 21 '15 at 01:19
  • i'm use the Web Framework is beego. it's have problem~? – nemo Jan 21 '15 at 01:38
  • the error code is " Post http://xvz.myserver.com:9000/path/create: EOF " – nemo Jan 21 '15 at 02:12

3 Answers3

20

It looks to me that you might be having the issue described in this answer. Basically, the Go http client will try to reuse connections unless you've specifically indicated that it shouldn't either in the Transport you've set your Client instance to use or on the request itself with:

request.Close = true

This becomes a problem when the server on the other end closes the connection without indicating so with a Connection: close header in a response. The net.http code assumes that the connection is still open and so the next request that tries to use the connection next, encounters the EOF from the connection being closed the other time.

You would need to check what is happening on the connection around the 1000th request. Is the receiving server set to limit the number of connections per client? Is your code running into a connection timeout? In either case, if it so happens the connection is closed by the server in a way that the Go Client code can't predict, then you'll run into the EOF.

Community
  • 1
  • 1
jeteon
  • 3,471
  • 27
  • 40
1
  • First, what for you instantiate new client each time client := &http.Client{... inside DoCreate() inside a loop? Client can be reusable even concurrently, so you can construct it more globally, say in main() seems to me.
  • Then for me such error looks like produced by RoundTrip, so by connection, so possibly from server site. Can you test with mocking server?
  • Finally if all that would not help, then yes, some systems have restriction on number of opened FileDescriptors which every net.Conn wants to have own. This restriction can be eliminated only on OS level.
Uvelichitel
  • 8,220
  • 1
  • 19
  • 36
1

The EOF is usually from a server not returning a complete header (including both CRLFs), or the connection is closed before the header is complete. It's more likely that your overloading your server with concurrent requests, though you should still make sure you have adequate resources locally for the number of concurrent requests you're making. If num is large enough, you're going to run out of something.

Though the error isn't really descriptive, it's not anything to worry about more so than any other request error. It's an error condition, and handle it like you would any others. If you want to know for certain, you'll likely have to have a packet capture of the connection that cause the EOF.

JimB
  • 104,193
  • 13
  • 262
  • 255