使用代理时转到泄漏goroutines

使用代理时转到泄漏goroutines,go,memory-leaks,goroutine,Go,Memory Leaks,Goroutine,请帮我解决我的问题。我写了检查代理的代码。一般来说,我运行50个goroutine,每个goroutine从通道获取代理,检查它是否工作,并从测试页面获得正确响应。 每个戈罗廷都建立了这种关系 请求-->代理-->我的测试页面-->我的测试页面中的测试内容 检查此关系的功能是: // GetAndCheckURL get test page via proxy and check its body. func GetAndCheckURL(c *http.Client, urlStr s

请帮我解决我的问题。我写了检查代理的代码。一般来说,我运行50个goroutine,每个goroutine从通道获取代理,检查它是否工作,并从测试页面获得正确响应。 每个戈罗廷都建立了这种关系

请求-->代理-->我的测试页面-->我的测试页面中的测试内容

检查此关系的功能是:

    // GetAndCheckURL get test page via proxy and check its body.
func GetAndCheckURL(c *http.Client, urlStr string) ([]byte, error) {
    resp, err := c.Get(urlStr)
    if err != nil {
        return nil, fmt.Errorf("request error: %v", err)

    }
    defer func() {
        if err := resp.Body.Close(); err != nil {
            packageLogger.Neverf("can't close response body, error: %v", err)
        }
    }()
    if body, err := ioutil.ReadAll(resp.Body); err != nil {
        packageLogger.Neverf("Can't read response body, URL '%s', error: %v, response statusCode: %d, status: %s\n", urlStr, err, resp.StatusCode, resp.Status)
        return nil, err
    } else if !bytes.Contains(body, []byte("<!--proxy_test")) {
        return nil, errors.New("invalid body")
    } else {
        return body, nil
    }
}
但问题是我得到的socks5代理的泄漏程序

 goroutine 160801 [IO wait, 915 minutes]:
internal/poll.runtime_pollWait(0x7fb2ab337410, 0x72, 0xc4206b96a8)
    /usr/local/Cellar/go/1.10.1/libexec/src/runtime/netpoll.go:173 +0x57
internal/poll.(*pollDesc).wait(0xc420c29998, 0x72, 0xffffffffffffff00, 0xb2e180, 0xe34418)
    /usr/local/Cellar/go/1.10.1/libexec/src/internal/poll/fd_poll_runtime.go:85 +0x9b
internal/poll.(*pollDesc).waitRead(0xc420c29998, 0xc422915e00, 0x2, 0x13)
    /usr/local/Cellar/go/1.10.1/libexec/src/internal/poll/fd_poll_runtime.go:90 +0x3d
internal/poll.(*FD).Read(0xc420c29980, 0xc422915ee0, 0x2, 0x13, 0x0, 0x0, 0x0)
    /usr/local/Cellar/go/1.10.1/libexec/src/internal/poll/fd_unix.go:157 +0x17d
net.(*netFD).Read(0xc420c29980, 0xc422915ee0, 0x2, 0x13, 0x0, 0x0, 0xe7c080)
    /usr/local/Cellar/go/1.10.1/libexec/src/net/fd_unix.go:202 +0x4f
net.(*conn).Read(0xc4214ec1b8, 0xc422915ee0, 0x2, 0x13, 0x0, 0x0, 0x0)
    /usr/local/Cellar/go/1.10.1/libexec/src/net/net.go:176 +0x6a
io.ReadAtLeast(0x7fb2ab62d868, 0xc4214ec1b8, 0xc422915ee0, 0x2, 0x13, 0x2, 0xa99f60, 0x0, 0x7fb2ab62d868)
    /usr/local/Cellar/go/1.10.1/libexec/src/io/io.go:309 +0x86
io.ReadFull(0x7fb2ab62d868, 0xc4214ec1b8, 0xc422915ee0, 0x2, 0x13, 0x0, 0x0, 0x0)
    /usr/local/Cellar/go/1.10.1/libexec/src/io/io.go:327 +0x58
vendor/golang_org/x/net/proxy.(*socks5).connect(0xc4208b6690, 0xb367c0, 0xc4214ec1b8, 0xc42083cd60, 0x11, 0xb367c0, 0xc4214ec1b8)
    /usr/local/Cellar/go/1.10.1/libexec/src/vendor/golang_org/x/net/proxy/socks5.go:113 +0x2f5
vendor/golang_org/x/net/proxy.(*socks5).Dial(0xc4208b6690, 0xabaa03, 0x3, 0xc42083cd60, 0x11, 0xc42083ce80, 0x12, 0xb367c0, 0xc4214ec1b8)
    /usr/local/Cellar/go/1.10.1/libexec/src/vendor/golang_org/x/net/proxy/socks5.go:75 +0xf3
net/http.(*Transport).dialConn(0xc420e1eff0, 0xb32400, 0xc420020078, 0xc420c29580, 0xc420024780, 0x5, 0xc42083cd60, 0x11, 0xae8d10, 0xc4229ee7b8, ...)
    /usr/local/Cellar/go/1.10.1/libexec/src/net/http/transport.go:1176 +0x6f7
net/http.(*Transport).getConn.func4(0xc420e1eff0, 0xb32400, 0xc420020078, 0xc421205a70, 0xc4209fa7e0)
    /usr/local/Cellar/go/1.10.1/libexec/src/net/http/transport.go:957 +0x78
created by net/http.(*Transport).getConn
    /usr/local/Cellar/go/1.10.1/libexec/src/net/http/transport.go:956 +0x363


我不知道我的错误在哪里。只有在添加连接截止日期(或ReadDailate和WriteDailine)时,我才能解决此问题。但我想解决我的超时问题。我尝试了许多超时的变体,但是这个漏洞是存在的。 在我的http.Transport-DisablekeepAlive为true时,net.Dialer和http.Client有超时


请帮帮我。

我也有类似的问题,也有泄漏goroutines的问题。 第一个是关于拨号程序中的KeepAlive超时,另一个是关于TLSHandshakeTimeout。有时我的程序被卡住了。下面的代码应该可以帮助您避免这种情况。希望它能帮助你)


你也可以在代码中添加你称之为goroutines的部分吗?我在问题中添加了粗体的解释,假设你正在某个地方关闭
proxyWaitChan
(你可以提供信息,如果你在哪里做的话),当
proxyWaitChan
关闭时,一些已执行的goroutine尚未完成执行,因此会泄漏。实际上,一个足够大的超时时间可以帮助你,但理论上,这并不能保证所有的goroutine都能完成。您需要将goroutine与主流同步(不确定是否要等待所有goroutine完成,或者让它们在一段时间后终止)。您可以使用其他通道和/或WaitGroup来实现这一点。
 goroutine 160801 [IO wait, 915 minutes]:
internal/poll.runtime_pollWait(0x7fb2ab337410, 0x72, 0xc4206b96a8)
    /usr/local/Cellar/go/1.10.1/libexec/src/runtime/netpoll.go:173 +0x57
internal/poll.(*pollDesc).wait(0xc420c29998, 0x72, 0xffffffffffffff00, 0xb2e180, 0xe34418)
    /usr/local/Cellar/go/1.10.1/libexec/src/internal/poll/fd_poll_runtime.go:85 +0x9b
internal/poll.(*pollDesc).waitRead(0xc420c29998, 0xc422915e00, 0x2, 0x13)
    /usr/local/Cellar/go/1.10.1/libexec/src/internal/poll/fd_poll_runtime.go:90 +0x3d
internal/poll.(*FD).Read(0xc420c29980, 0xc422915ee0, 0x2, 0x13, 0x0, 0x0, 0x0)
    /usr/local/Cellar/go/1.10.1/libexec/src/internal/poll/fd_unix.go:157 +0x17d
net.(*netFD).Read(0xc420c29980, 0xc422915ee0, 0x2, 0x13, 0x0, 0x0, 0xe7c080)
    /usr/local/Cellar/go/1.10.1/libexec/src/net/fd_unix.go:202 +0x4f
net.(*conn).Read(0xc4214ec1b8, 0xc422915ee0, 0x2, 0x13, 0x0, 0x0, 0x0)
    /usr/local/Cellar/go/1.10.1/libexec/src/net/net.go:176 +0x6a
io.ReadAtLeast(0x7fb2ab62d868, 0xc4214ec1b8, 0xc422915ee0, 0x2, 0x13, 0x2, 0xa99f60, 0x0, 0x7fb2ab62d868)
    /usr/local/Cellar/go/1.10.1/libexec/src/io/io.go:309 +0x86
io.ReadFull(0x7fb2ab62d868, 0xc4214ec1b8, 0xc422915ee0, 0x2, 0x13, 0x0, 0x0, 0x0)
    /usr/local/Cellar/go/1.10.1/libexec/src/io/io.go:327 +0x58
vendor/golang_org/x/net/proxy.(*socks5).connect(0xc4208b6690, 0xb367c0, 0xc4214ec1b8, 0xc42083cd60, 0x11, 0xb367c0, 0xc4214ec1b8)
    /usr/local/Cellar/go/1.10.1/libexec/src/vendor/golang_org/x/net/proxy/socks5.go:113 +0x2f5
vendor/golang_org/x/net/proxy.(*socks5).Dial(0xc4208b6690, 0xabaa03, 0x3, 0xc42083cd60, 0x11, 0xc42083ce80, 0x12, 0xb367c0, 0xc4214ec1b8)
    /usr/local/Cellar/go/1.10.1/libexec/src/vendor/golang_org/x/net/proxy/socks5.go:75 +0xf3
net/http.(*Transport).dialConn(0xc420e1eff0, 0xb32400, 0xc420020078, 0xc420c29580, 0xc420024780, 0x5, 0xc42083cd60, 0x11, 0xae8d10, 0xc4229ee7b8, ...)
    /usr/local/Cellar/go/1.10.1/libexec/src/net/http/transport.go:1176 +0x6f7
net/http.(*Transport).getConn.func4(0xc420e1eff0, 0xb32400, 0xc420020078, 0xc421205a70, 0xc4209fa7e0)
    /usr/local/Cellar/go/1.10.1/libexec/src/net/http/transport.go:957 +0x78
created by net/http.(*Transport).getConn
    /usr/local/Cellar/go/1.10.1/libexec/src/net/http/transport.go:956 +0x363
    goroutine 18553 [chan receive, 27 minutes]:
net/http.(*Transport).getConn.func2.1(0x1a7c8900, 0x19b8ff40, 0x84f7388)
    /usr/local/go/src/net/http/transport.go:946 +0x41
created by net/http.(*Transport).getConn.func2
    /usr/local/go/src/net/http/transport.go:945 +0x61
&http.Transport{
        DialContext: (&net.Dialer{
            Timeout:   5 * time.Second,
            KeepAlive: 5 * time.Second,
            DualStack: true,
        }).DialContext,
        TLSHandshakeTimeout:   2 * time.Second,
        ResponseHeaderTimeout: 2 * time.Second,
        ExpectContinueTimeout: 1 * time.Second,
        DisableKeepAlives:     true,
    }