你正在使用哪个版本的Go(go version
)?
$ go version
go1.16.5 darwin/amd64
这个问题在最新版本中是否重现?
是的
你正在使用什么操作系统和处理器架构(go env
)?
go env
输出
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/amandachow/Library/Caches/go-build"
GOENV="/Users/amandachow/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/amandachow/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/amandachow/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GOVCS=""
GOVERSION="go1.16.5"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/_f/1tl8g2w95wx34b7zp53y0kqc0000gp/T/go-build310981905=/tmp/go-build -gno-record-gcc-switches -fno-common"
问题是什么?
我使用了httputil.ReverseProxy与http2.Transport。下游客户端遇到了看起来像是连接抖动的问题——要么收到RST_STREAM关闭的流,要么从我们的ErrorHandler接收到错误响应。经过一些调查,我发现当http2.Server端关闭一个流时,它会触发一个竞争条件。同时,http2.Transport端在处理 Dataframe 时关闭了流,这导致整个TCP客户端连接出错并关闭。这是在这里描述的相同问题:https://go.googlesource.com/net/+/6c4ac8bdbf06a105c4baf3dcda28bd9b0fb15588
流在clientconn解锁和bufpipe写之间被关闭。尝试写入已关闭的bufpipe时出错,因此关闭了整个clientconn,使所有其他打开的流出现错误。
我尝试保持对bufpipe写锁的持有。我对代码进行了以下更改,并将其运行到生产环境中,然后看到错误停止:
// Check connection-level flow control.
cc.mu.Lock()
+ defer cc.mu.Unlock()
if cs.inflow.available() >= int32(f.Length) {
cs.inflow.take(int32(f.Length))
} else {
- cc.mu.Unlock()
return ConnectionError(ErrCodeFlowControl)
}
// Return any padded flow control now, since we won't
@@ -2246,11 +2246,13 @@ func (rl *clientConnReadLoop) processData(f *DataFrame) error {
cc.bw.Flush()
cc.wmu.Unlock()
}
- cc.mu.Unlock()
if len(data) > 0 && !didReset {
if _, err := cs.bufPipe.Write(data); err != nil {
rl.endStreamError(cs, err)
return err
}
4条答案
按热度按时间jjjwad0x1#
CC @neild via https://dev.golang.org/owners
vfh0ocws2#
请在这个问题上快速ping一下!我们仍然在我们的PROD环境中看到这个问题。
tp5buhyn3#
嘿,友好的ping一下这个 - 你还需要其他细节吗?
tvmytwxo4#
我看到了这个重构PR,其中cc锁被用于bufpipe写操作:golang/net@cedda3a#diff-e9bd9b4a514c2960ad85405e4a827d83c2decaaac70e9e0158a59db2d05807a7R2410-R2425
看起来这将解决我们的问题——有人能确认一下吗?