go x/net/http2:在最近的版本中,HTTP/2出现了稳定的性能退化现象,

6qftjkof  于 2个月前  发布在  Go
关注(0)|答案(6)|浏览(28)

你好,我在Couchbase的全文搜索引擎工作,我们最近将我们的散列收集协议迁移到了使用x/net/http2而不是net/http。我们目前使用的Go版本是go-1.9.3。在内部的一些测试中,我注意到当我升级了使用的x/net发布版本时,全文索引上的查询吞吐量会下降(这些数字是在运行在centos7上的系统上得出的)。
| 分支 | 查询吞吐量 |
| ------------ | ------------ |
| release-branch.go1.6 | 27734 q/s |
| release-branch.go1.7 | 17037 q/s |
| release-branch.go1.8 | 15139 q/s |
| release-branch.go1.9 | 14836 q/s |
| release-branch.go1.10 | 9500 q/s |
| master | 8336 q/s |
这是我们在代码中使用x/net/http2的传输设置散列收集客户端的方式:

transport2 := &http2.Transport{
	TLSClientConfig: clientTLSConfig,
}
cbft.Http2Client = &http.Client{Transport: transport2}

这里是服务器的设置方式,它也使用x/net/netutil来设置LimitListener:

listener, _ := net.Listen("tcp", bindHTTP)
server := &http.Server{Addr: bindHTTP,
    Handler:      routerInUse,
    ReadTimeout:  httpReadTimeout,
    WriteTimeout: httpWriteTimeout
}
...
keepAliveListener := tcpKeepAliveListener{listener.(*net.TCPListener)}
limitListener := netutil.LimitListener(keepAliveListener, httpMaxConnections)
tlsListener := tls.NewListener(limitListener, serverTLSConfig)
...
_ = server.Serve(tlsListener)

我想知道这方面是否有什么已知的问题,或者在x/net的后续版本中是否有需要调整的其他设置。我还尝试编写了一个基于您当前测试的简单服务器客户端基准测试单元测试,看看它是否能指出什么明显的问题......

func BenchmarkServerClient(b *testing.B) {
	b.ReportAllocs()

	const (
		itemSize = 1 << 10
		itemCount = 1000
	)

	st := newServerTester(b, func(w http.ResponseWriter, r *http.Request) {
		for i := 0; i < itemCount; i++ {
			_, err := w.Write(make([]byte, itemSize))
			if err != nil {
				return
			}
		}
	}, optOnlyServer)
	defer st.Close()

	tlsConfig := &tls.Config{
		InsecureSkipVerify: true,
	}

	tr := &Transport{TLSClientConfig: tlsConfig}
	defer tr.CloseIdleConnections()
	cl := &http.Client{Transport: tr}

	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		resp, err := cl.Get(st.ts.URL)
		if err != nil {
			b.Fatal(err)
		}

		resp.Body.Close()
	}
}

以下是我计算机上上述基准测试的结果(在OSX 10.13.4上):

release-branch.go1.6   	    BenchmarkServerClient-8   	    2000	    742842 ns/op	   18715 B/op	      64 allocs/op
release-branch.go1.7   	    BenchmarkServerClient-8   	    2000	    554580 ns/op	   20688 B/op	      83 allocs/op
release-branch.go1.8   	    BenchmarkServerClient-8   	    2000	    631001 ns/op	   20728 B/op	      84 allocs/op
release-branch.go1.9   	    BenchmarkServerClient-8   	    2000	    675503 ns/op	   19745 B/op	      87 allocs/op
release-branch.go1.10       BenchmarkServerClient-8   	    2000	    772618 ns/op	   19087 B/op	      89 allocs/op
master   	       	    BenchmarkServerClient-8   	    2000	    930152 ns/op	   19212 B/op	      89 allocs/op

尽管我无法准确地重现这个问题(在这里,异常出现在1.6版本),但从1.7到master版本,每个操作所花费的时间确实有所下降。这是我系统的go env输出:

GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/abhinavdangeti/Library/Caches/go-build"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/abhinavdangeti/Documents/go"
GORACE=""
GOROOT="/usr/local/Cellar/go/1.10.1/libexec"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.10.1/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/ln/vkg1npcj5tz0ps359y6fwmn80000gn/T/go-build266872403=/tmp/go-build -gno-record-gcc-switches -fno-common"

我希望得到关于我观察到的任何指针或建议。

kmb7vmvb

kmb7vmvb2#

我能够重现这些 BenchmarkServerClient 减速:

  • 1.7 -> 1.8
  • 1.8 -> 1.9
  • 1.9 -> 1.10

1.9 -> 1.10 是由于 https://go-review.googlesource.com/71372 引起的。我还没有关于如何改进的建议,以及 1.7->1.8/1.8->1.9 减速的原因或者我们需要修复的问题。
对于 BenchmarkServerClient ,这个问题中声称的最大降级是 1.10 -> master。但是我无法重现这种减速。@abhinavdangeti ,你能请你指定你运行基准测试时 master 的提交吗?例如,当我在 golang/net@640f462 运行它时,我几乎看不到从 1.10 的降级。

toe95027

toe950273#

嘿,@meirf ,感谢你确认了之前版本的减速情况。
这是我上次测试时得到的提示:golang/net@5f9ae10
然而,我刚刚在主线上重新运行了几次测试,这个数字看起来与我之前报告的有些不同......它似乎更接近1.10,但性能仍然有所下降。.

BenchmarkServerClient-8   	    2000	    849227 ns/op	   19133 B/op	      89 allocs/op

我用所有分支的最新代码重新运行了测试,以下是结果。你是对的,我没有看到1.10和主线上之间的巨大差距。所以我之前看到的可能是异常情况。.

goos: darwin
goarch: amd64
pkg: golang.org/x/net/http2
release-branch.go1.6    BenchmarkServerClient-8   	    2000	    754807 ns/op	   19309 B/op	      64 allocs/op
release-branch.go1.7    BenchmarkServerClient-8   	    3000	    550916 ns/op	   20445 B/op	      83 allocs/op
release-branch.go1.8    BenchmarkServerClient-8   	    2000	    617894 ns/op	   20441 B/op	      84 allocs/op
release-branch.go1.9    BenchmarkServerClient-8   	    2000	    673070 ns/op	   19736 B/op	      87 allocs/op
release-branch.go1.10   BenchmarkServerClient-8   	    2000	    792244 ns/op	   19101 B/op	      89 allocs/op
master                  BenchmarkServerClient-8   	    2000	    783671 ns/op	   19086 B/op	      89 allocs/op
exdqitrt

exdqitrt4#

如果正确地阅读了这些结果,你也看到了从1.6到1.7的显著加速,而之前你看到的是显著下降。这是正确的吗?
如果是这样的话,消除测试机器上的噪声(包括热效应!)可能会有所帮助,看看剩余效果有多显著。(请注意,benchcmp可以比较任意多个基准运行的结果。)

qvsjd97n

qvsjd97n5#

嗯,没关系。你在原始帖子中也有这个问题:你观察到的吞吐量数字为什么不跟踪基准时间?

vm0i2vca

vm0i2vca6#

嘿,@bcmills,这部分对我来说仍然有点困惑 - 为什么我们的吞吐量数字与从1.6到1.7的基准时钟不匹配,但重复的测试已经显示了这种回归。

相关问题