-
Notifications
You must be signed in to change notification settings - Fork 17.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
x/net/http2: implementation issue #48111
Comments
I have mentioned one of the problems in #39389 along with a review message inside its Pull Request golang/net#73. |
@nekomeowww could you share the source code of an example for this issue? Also could you reword and re-title the issue to remove the duplicates from #39389 so it is clearer what the new issue is? Thanks. cc @neild |
Source code to reproduce: func ServeTLS(certPath, certKeyPath string, r *gin.Engine, port int, h ...GinHandler) string {
for i := range h {
h[i].Mount(r)
}
l, err := net.Listen("tcp", net.JoinHostPort("127.0.0.1", strconv.Itoa(port)))
if err != nil {
panic(err)
}
go func() {
err := http.ServeTLS(l, r, certPath, certKeyPath)
if err != nil {
panic(err)
}
}()
time.Sleep(100 * time.Millisecond)
return l.Addr().String()
}
func TestTimeout(t *testing.T) {
assert := assert.New(t)
require := require.New(t)
caCertPath := "../testdata/ca.crt"
certPath := "../testdata/server.crt"
certKeyPath := "../testdata/server.pem"
err := generateCerts()
require.NoError(err)
defer func() {
err = os.Remove(caCertPath)
assert.NoError(err)
err = os.Remove(certPath)
assert.NoError(err)
err = os.Remove(certKeyPath)
assert.NoError(err)
}()
r := gin.New()
h := timeoutHandler{}
addr := ServeTLS(certPath, certKeyPath, r, 0, &h)
c := &http.Client{
Timeout: time.Second,
}
c.Transport = http2.Transport{}
maxTryout := 100000
var wg sync.WaitGroup
errorCount := 0
for i := 0; i < maxTryout; i++ {
wg.Add(1)
go func(idx int) {
defer wg.Done()
uri := fmt.Sprintf("https://%s/normal/%d?timeout=1", addr, idx)
req, err := http.NewRequest(http.MethodGet, uri, nil)
require.NoError(err)
_, _ = c.Do(req)
}(i)
wg.Add(1)
go func(idx int) {
defer wg.Done()
uri := fmt.Sprintf("https://%s/normal/%d?timeout=0", addr, idx)
req, err := http.NewRequest(http.MethodGet, uri, nil)
require.NoError(err)
_, err = c.Do(req)
if err != nil {
errorCount++
}
}(i)
}
Debugf("current error count: %d", errorCount)
for i := 0; i < 100; i++ {
uri := fmt.Sprintf("https://%s/normal/%d?timeout=0", addr, i)
req, err := http.NewRequest(http.MethodGet, uri, nil)
require.NoError(err)
_, err = c.Do(req)
if err != nil {
errorCount++
}
}
wg.Wait()
Debugf("ended, report: %d/%d, errored percentage: %d%%", errorCount, maxTryout, (errorCount/maxTryout)*100)
} There were some chang later we researched the source code, net/http2 provides a new method called c.Transport = http2.Transport{} // old
c.Transport, err = http2.ConfigureTransports(&http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
}) // new By using the test code above, we can find out many problems:
Well, we could solve all these problems by overriding the implementation of
I just mentioned it above. And also, most of the implementation of http2 seems to consider the usage environment in an End User to Service way, not the Service to Service way (Such as gRPC).
In this case, we need more control of the client (microservice), dynamically change the limitation of the client can be established at different time aspect by referencing the bandwidth which user and services consume. To make sure the calling stacks are stable, we will also need the ability to control the pipeline, terminate the long and dead connections for better performance. |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Used default
http2.Transport{}
and set to ahttp.Client.Transport
, and established many connections to the http2 server.What did you expect to see?
There are two different problems we are expecting to improve:
http2.Transport
needs to export aMaxConcurrentStreams
field to achieve thishttp.Client
orhttp2.Transport
needs to export some error indication fields to achieve this.What did you see instead?
context deadline exceeded (Client.Timeout exceeded while awaiting headers)
)The text was updated successfully, but these errors were encountered: