Возможное состояние гонки с реализацией http2 - PullRequest
0 голосов
/ 30 января 2019

У меня возникла любопытная проблема, которая очень редко случается в производстве.

У меня есть глобальный http-клиент для повторного использования соединений.

DefaultClient = &http.Client{
    Transport: &http.Transport{
        Proxy: http.ProxyFromEnvironment,
        DialContext: (&net.Dialer{
            Timeout:   500 * time.Millisecond,
            KeepAlive: 1 * time.Minute,
        }).DialContext,
        TLSHandshakeTimeout: 500 * time.Millisecond,
        MaxIdleConns:        3000,
        MaxIdleConnsPerHost: 3000,
        IdleConnTimeout:     1 * time.Minute,
    },
    Timeout: 500 * time.Millisecond,
}

Время от времени машина перестает отвечать на запросы, потому что не может восстановиться после паники, которая, по-видимому, связана с блокировкой и разблокировкой мьютекса в стандартном http-каталоге Go.

goroutine 47888935 [semacquire, 7 minutes]:
sync.runtime_SemacquireMutex(0xc00040126c, 0x0)
    /usr/local/go/src/runtime/sema.go:71 +0x3d
sync.(*Mutex).Lock(0xc000401268)
    /usr/local/go/src/sync/mutex.go:134 +0xff
net/http.(*http2clientConnPool).getClientConn(0xc000401260, 0xc028295f00, 0xc0281de820, 0x12, 0xc00027a400, 0xc0283266a8, 0x6aafa0, 0xc00027a410)
    /usr/local/go/src/net/http/h2_bundle.go:760 +0x65
net/http.http2noDialClientConnPool.GetClientConn(0xc000401260, 0xc028295f00, 0xc0281de820, 0x12, 0xc0281de820, 0x12, 0x0)
    /usr/local/go/src/net/http/h2_bundle.go:954 +0x4e
net/http.(*http2Transport).RoundTripOpt(0xc00027a410, 0xc028295f00, 0x0, 0x200000000000000, 0x4137ec, 0xb940aa)
    /usr/local/go/src/net/http/h2_bundle.go:7031 +0x105
net/http.(*http2Transport).RoundTrip(0xc00027a410, 0xc028295f00, 0x1, 0xc028307800, 0x0)
    /usr/local/go/src/net/http/h2_bundle.go:6999 +0x3a
net/http.http2noDialH2RoundTripper.RoundTrip(0xc00027a410, 0xc028295f00, 0xc0282cf800, 0x5, 0xc00059c2c8)
    /usr/local/go/src/net/http/h2_bundle.go:1019 +0x39
net/http.(*Transport).roundTrip(0xc000177680, 0xc028295f00, 0xc028267a70, 0xc02801ff88, 0xc02801ff90)
    /usr/local/go/src/net/http/transport.go:415 +0xd4c
net/http.(*Transport).RoundTrip(0xc000177680, 0xc028295f00, 0xc000177680, 0xbf0c9388b63791ca, 0x2122772ff0fc)
    /usr/local/go/src/net/http/roundtrip.go:17 +0x35
net/http.send(0xc028295e00, 0xc99600, 0xc000177680, 0xbf0c9388b63791ca, 0x2122772ff0fc, 0x11d03a0, 0xc027ef3480, 0xbf0c9388b63791ca, 0xc028326cb8, 0x1)
    /usr/local/go/src/net/http/client.go:250 +0x14b
net/http.(*Client).send(0xc000400360, 0xc028295e00, 0xbf0c9388b63791ca, 0x2122772ff0fc, 0x11d03a0, 0xc027ef3480, 0x0, 0x1, 0xc000518000)
    /usr/local/go/src/net/http/client.go:174 +0xfa
net/http.(*Client).do(0xc000400360, 0xc028295e00, 0x0, 0x0, 0x0)
    /usr/local/go/src/net/http/client.go:641 +0x2a8
net/http.(*Client).Do(0xc000400360, 0xc028295e00, 0x10, 0xb933f5, 0x4)
    /usr/local/go/src/net/http/client.go:509 +0x35

Это случается так редко в условиях интенсивного трафика, что трудно воспроизвести.

Кто-нибудь сталкивался с этим раньше или знает о возможной проблеме?Кажется, он тесно связан с http-клиентом.

...