Go http get crashes on retrieving high-latency resources

时间:2015-10-30 22:41:38

标签: http go

I have a panicking program which intends to illustrate the issue of retrieving high-latency resources via golang's http client.

Does someone have a clue why this is happening?

go version go1.5.1 linux/amd64

package main

import ("fmt"
    "net/http"
    "time"
    "net")

func main() {


    for i:=0; i<2000; i++ {
        start := time.Now()

         client := &http.Client{} // this enough for the program to crash
        /*client := &http.Client{
            Transport: &http.Transport{
                Dial: (&net.Dialer{
                    Timeout:   1 * time.Second,
                    KeepAlive: 0,
                }).Dial,
                DisableKeepAlives: true,
                DisableCompression: true,
                MaxIdleConnsPerHost: 1,
                ResponseHeaderTimeout: 1*time.Second,
            },
        }*/

        req, _ := http.NewRequest("GET", "http://mickle.com.au/wp-content/uploads/2015/03/11222.jpg", nil)
        req.Header.Add("Connection", "close")
        req.Header.Add("Accept-Encoding", "none")

        response, _ := client.Do(req)
        fmt.Printf("httpreq took %s. resp status: %s\n", time.Since(start), response.Status)
        response.Body.Close()
    }
}

http://play.golang.org/p/nMnFb_x2yU

httpreq took 817.750359ms. resp status: 200 OK
httpreq took 798.177493ms. resp status: 200 OK
[[... left out 33 lines...]]
httpreq took 795.433486ms. resp status: 200 OK
httpreq took 805.610082ms. resp status: 200 OK
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x0 pc=0x4014a6]

goroutine 1 [running]:
main.main()
    /home/bongo/Downloads/a.go:32 +0x4a6

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
    /usr/lib/golang/src/runtime/asm_amd64.s:1696 +0x1

goroutine 8 [select]:
net/http.(*persistConn).readLoop(0xc8200ac000)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 9 [select]:
net/http.(*persistConn).writeLoop(0xc8200ac000)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 40 [select]:
net/http.(*persistConn).readLoop(0xc8200ac2c0)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 76 [select]:
net/http.(*persistConn).readLoop(0xc8200e22c0)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 34 [select]:
net/http.(*persistConn).readLoop(0xc8200e2000)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 35 [select]:
net/http.(*persistConn).writeLoop(0xc8200e2000)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 12 [select]:
net/http.(*persistConn).readLoop(0xc8200ac0b0)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 13 [select]:
net/http.(*persistConn).writeLoop(0xc8200ac0b0)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 16 [select]:
net/http.(*persistConn).readLoop(0xc8200ac160)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 50 [select]:
net/http.(*persistConn).writeLoop(0xc8200ac160)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 38 [select]:
net/http.(*persistConn).readLoop(0xc82010e000)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 39 [select]:
net/http.(*persistConn).writeLoop(0xc82010e000)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 53 [select]:
net/http.(*persistConn).readLoop(0xc8200ac210)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 54 [select]:
net/http.(*persistConn).writeLoop(0xc8200ac210)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 61 [select]:
net/http.(*persistConn).readLoop(0xc8200e2160)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 41 [select]:
net/http.(*persistConn).writeLoop(0xc8200ac2c0)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 44 [select]:
net/http.(*persistConn).readLoop(0xc82010e0b0)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 45 [select]:
net/http.(*persistConn).writeLoop(0xc82010e0b0)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 59 [select]:
net/http.(*persistConn).readLoop(0xc8200ac370)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 60 [select]:
net/http.(*persistConn).writeLoop(0xc8200ac370)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 22 [select]:
net/http.(*persistConn).readLoop(0xc8200e20b0)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 23 [select]:
net/http.(*persistConn).writeLoop(0xc8200e20b0)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 78 [select]:
net/http.(*persistConn).readLoop(0xc8200e2370)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 62 [select]:
net/http.(*persistConn).writeLoop(0xc8200e2160)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 48 [select]:
net/http.(*persistConn).readLoop(0xc82010e160)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 49 [select]:
net/http.(*persistConn).writeLoop(0xc82010e160)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 28 [select]:
net/http.(*persistConn).readLoop(0xc8200e2210)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 29 [select]:
net/http.(*persistConn).writeLoop(0xc8200e2210)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 70 [select]:
net/http.(*persistConn).readLoop(0xc8200ac420)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 68 [select]:
net/http.(*persistConn).readLoop(0xc820170000)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 69 [select]:
net/http.(*persistConn).writeLoop(0xc820170000)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 101 [select]:
net/http.(*persistConn).readLoop(0xc8201702c0)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 71 [select]:
net/http.(*persistConn).writeLoop(0xc8200ac420)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 74 [select]:
net/http.(*persistConn).readLoop(0xc8201700b0)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 75 [select]:
net/http.(*persistConn).writeLoop(0xc8201700b0)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 84 [select]:
net/http.(*persistConn).readLoop(0xc82010e210)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 85 [select]:
net/http.(*persistConn).writeLoop(0xc82010e210)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 99 [select]:
net/http.(*persistConn).readLoop(0xc8200ac4d0)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 100 [select]:
net/http.(*persistConn).writeLoop(0xc8200ac4d0)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 88 [select]:
net/http.(*persistConn).readLoop(0xc82010e2c0)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 89 [select]:
net/http.(*persistConn).writeLoop(0xc82010e2c0)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 80 [select]:
net/http.(*persistConn).readLoop(0xc82010e370)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 77 [select]:
net/http.(*persistConn).writeLoop(0xc8200e22c0)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 122 [select]:
net/http.(*persistConn).readLoop(0xc820170160)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 79 [select]:
net/http.(*persistConn).writeLoop(0xc8200e2370)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 116 [select]:
net/http.(*persistConn).readLoop(0xc8200e2420)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 117 [select]:
net/http.(*persistConn).writeLoop(0xc8200e2420)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 120 [select]:
net/http.(*persistConn).readLoop(0xc8200e24d0)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 121 [select]:
net/http.(*persistConn).writeLoop(0xc8200e24d0)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 81 [select]:
net/http.(*persistConn).writeLoop(0xc82010e370)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 147 [select]:
net/http.(*persistConn).readLoop(0xc8200e2580)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 123 [select]:
net/http.(*persistConn).writeLoop(0xc820170160)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 134 [select]:
net/http.(*persistConn).readLoop(0xc820170210)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 135 [select]:
net/http.(*persistConn).writeLoop(0xc820170210)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 178 [select]:
net/http.(*persistConn).readLoop(0xc82010e580)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 102 [select]:
net/http.(*persistConn).writeLoop(0xc8201702c0)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 105 [select]:
net/http.(*persistConn).readLoop(0xc8200ac580)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 106 [select]:
net/http.(*persistConn).writeLoop(0xc8200ac580)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 109 [select]:
net/http.(*persistConn).readLoop(0xc8200ac630)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 110 [select]:
net/http.(*persistConn).writeLoop(0xc8200ac630)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 113 [select]:
net/http.(*persistConn).readLoop(0xc8200ac6e0)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 146 [select]:
net/http.(*persistConn).writeLoop(0xc8200ac6e0)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 140 [select]:
net/http.(*persistConn).readLoop(0xc820170370)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 141 [select]:
net/http.(*persistConn).writeLoop(0xc820170370)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 144 [select]:
net/http.(*persistConn).readLoop(0xc820170420)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 145 [select]:
net/http.(*persistConn).writeLoop(0xc820170420)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 94 [select]:
net/http.(*persistConn).readLoop(0xc82010e420)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 95 [select]:
net/http.(*persistConn).writeLoop(0xc82010e420)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 162 [select]:
net/http.(*persistConn).readLoop(0xc82010e4d0)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 163 [select]:
net/http.(*persistConn).writeLoop(0xc82010e4d0)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 179 [select]:
net/http.(*persistConn).writeLoop(0xc82010e580)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 126 [select]:
net/http.(*persistConn).readLoop(0xc82010e630)
    /usr/lib/golang/src/net/http/transport.go:976 +0xac7
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:685 +0xc78

goroutine 148 [select]:
net/http.(*persistConn).writeLoop(0xc8200e2580)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d

goroutine 127 [select]:
net/http.(*persistConn).writeLoop(0xc82010e630)
    /usr/lib/golang/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
    /usr/lib/golang/src/net/http/transport.go:686 +0xc9d
exit status 2

2 个答案:

答案 0 :(得分:3)

The request is getting an error which you're just ignoring and then you get a nil pointer dereference when you attempt to access the response status in the Printf on the next line.

Here is your example printing the error; http://play.golang.org/p/V8BCrM_Ag7

Every request gets this; Get http://mickle.com.au/wp-content/uploads/2015/03/11222.jpg: dial tcp: Protocol not available

Basically, you need to assign the error to something and check it before you allow execution to continue. The common syntax would look like this;

if response, err := client.Do(req); err != nil {
   // handles error and return
}

答案 1 :(得分:0)

导致我走向错误方向的错误是访问一个nil指针,这导致一个完全挂起的程序。原始问题也在此处描述:https://groups.google.com/d/msg/golang-nuts/9mtbzTFTz5E/Z_rrqF8ADAAJ