http - 可能的竞争条件 使用 http2 实现
问题描述
我有一个奇怪的问题,在生产中很少发生。
我有一个 gobal 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,
}
每隔一段时间,机器就会因为无法从恐慌中恢复而变得无响应,这似乎与 Go 标准 http 库中的互斥锁和解锁有关。
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 客户端紧密耦合。
解决方案
推荐阅读
- docker - EC2 - Docker 容器目录的大小增加
- vue.js - 使用 foreignObject 将 scopedSlot 插入 d3 svg
- javascript - 如何在 React 中全局激活 useEffect?
- actions-on-google - Google 模拟器上的操作无法刷新
- r - 匹配两个数据框之间的字符串并将缺失的字符串添加到 R 中不完整的字符串
- haxe - Lime 无法构建为 html5。编译给出了许多我不知道如何修复的错误
- postgresql - NpgSql 和 PostgreSQL 12.4 - 仅从数据读取器获取游标名称而不是数据行
- kotlin - 如何在 moshi (kotlin) 中解析 LinkedHashMap
- java - UndertowJaxrsServer.deploy 和 UndertowJaxrsServer.deployOldStyle 有什么区别?
- python - 如何根据用fuzzywuzzy比率计算的相似度得分从列表中消除重复字符串?