Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go HTTP客户端挂起_Go - Fatal编程技术网

Go HTTP客户端挂起

Go HTTP客户端挂起,go,Go,我有一些代码可以生成大量简单的HTTP GET请求 我使用的客户端设置如下: type client struct { *http.Client // other stuff in here } func NewClient() client { var c client c.Client = &http.Client{ CheckRedirect: func(req *http.Request, via []*http.Request)

我有一些代码可以生成大量简单的HTTP GET请求

我使用的客户端设置如下:

type client struct {
    *http.Client
    // other stuff in here
}

func NewClient() client {
    var c client
    c.Client = &http.Client{
        CheckRedirect: func(req *http.Request, via []*http.Request) error {
            req.Header.Set("User-Agent", c.userAgent)
            return nil
        },
        Transport: &http.Transport{
            Dial: func(network, addr string) (net.Conn, error) {
                return net.DialTimeout(network, addr, 2*time.Second)
            },
            TLSHandshakeTimeout: 2 * time.Second,
            TLSClientConfig: &tls.Config{
                InsecureSkipVerify: true,
            },
        },
        Timeout: 2 * time.Second,
    }
    return c
}
req, err := http.NewRequest("GET", url, nil)
正如你所看到的,我真的在努力确保我的坏连接超时。我提出如下要求:

type client struct {
    *http.Client
    // other stuff in here
}

func NewClient() client {
    var c client
    c.Client = &http.Client{
        CheckRedirect: func(req *http.Request, via []*http.Request) error {
            req.Header.Set("User-Agent", c.userAgent)
            return nil
        },
        Transport: &http.Transport{
            Dial: func(network, addr string) (net.Conn, error) {
                return net.DialTimeout(network, addr, 2*time.Second)
            },
            TLSHandshakeTimeout: 2 * time.Second,
            TLSClientConfig: &tls.Config{
                InsecureSkipVerify: true,
            },
        },
        Timeout: 2 * time.Second,
    }
    return c
}
req, err := http.NewRequest("GET", url, nil)
那里没有什么不寻常的事。但过了一段时间,我发现这些goroutine正在构建并阻塞,这是一个在恐慌之后获取跟踪的示例:

goroutine 325 [select, 4 minutes]:
net/http.(*persistConn).writeLoop(0xc208075130)
    /usr/local/go/src/net/http/transport.go:945 +0x41d
created by net/http.(*Transport).dialConn
    /usr/local/go/src/net/http/transport.go:661 +0xcbc

goroutine418[IO等待,4分钟]:
net。(*pollDesc)。等待(0xc2083c7870、0x72、0x0、0x0)
/usr/local/go/src/net/fd_poll_runtime.go:84+0x47
net(*pollDesc).WaitRead(0xc2083c7870,0x0,0x0)
/usr/local/go/src/net/fd\u poll\u运行时。go:89+0x43
读取(0xc2083c7810、0xc20857e000、0x1000、0x1000、0x0、0x7FBB634C3B0、0xc2084d87a0)
/usr/local/go/src/net/fd_unix.go:242+0x40f
读取(0xc208116020、0xc20857e000、0x1000、0x1000、0x0、0x0、0x0)
/usr/local/go/src/net/net.go:121+0xdc
net/http.NoteofReader.Read(0x7fbb634c7288、0xc208116020、0xc208075b28、0xc20857e000、0x1000、0x1000、0x678100、0x0、0x0)
/usr/local/go/src/net/http/transport.go:1270+0x6e
net/http。(*NoteoFreader).Read(0xc2083d84c0,0xc20857e000,0x1000,0xc208017600,0x0,0x0)
:125+0xd4
bufio.(*读卡器).填充(0xc20858c0c0)
/usr/local/go/src/bufio/bufio.go:97+0x1ce
bufio.(*读卡器).Peek(0xc20858c0c0,0x1,0x0,0x0,0x0,0x0,0x0)
/usr/local/go/src/bufio/bufio.go:132+0xf0
net/http。(*persistConn).readLoop(0xc208075ad0)
/usr/local/go/src/net/http/transport.go:842+0xa4
由网络/http创建。(*传输)。拨号连接
/usr/local/go/src/net/http/transport.go:660+0xc9f
我一直在尝试观看
netstat
tcpdump
,看看他们到底在做什么,但现在证明它不是很有用。在深入到源代码或更加认真地监控之前,我想我会把这个问题抛到一边。这是怎么回事

还有,为什么我的超时不起作用?是否需要设置另一个超时?(正如您所看到的,我一直在设置我能找到的每一个响应头超时,可能我也应该设置响应头超时?我认为http.Client结构中的超时非常可靠,可以超时任何内容)

最后,有没有办法设置我丢失的客户端端口,以便更好地监视哪些连接出现问题


编辑:作为记录,我也非常确定我正在阅读/关闭每个请求的响应主体。除非有一些消息因超时或我不知道的原因而挂起,但如果这是唯一的解决方案,我会再次查看。

结果表明,这不是问题所在,它们似乎只是保持活动的消息(尽管奇怪的是,我设置了
KeepAlive:0
集?)。将
Done()
放错
sync上。WaitGroup
才是真正的罪魁祸首。我想我开始把每个
Wait()
看作是被
http.Client
调用的,而不是
sync.WaitGroup

也许这个问题的答案可能会有所帮助。嗯,我不知道,除了确保你读了整件事之外,这个问题似乎没有结论,实际上,我使用的方法是,在调用
Close()
之前,answer指定
io.Copy(ioutil.Discard,r.Body)
,只是为了确定它是可读的,你的程序是否在某个地方被阻塞了?这看起来像是“保持活力”的连接。我刚刚注意到现在。。。看起来问题实际上可能出在
sync.WaitGroup
;)我假设当你说你有
KeepAlive:0
,你指的是网络拨号程序中的设置,因为在http中没有类似的设置。这是针对tcp keepalive的,它与http keepalive完全不同,http keepalive只是可以重用的连接。哦,谢谢你,我不知道,我是指拨号程序。