-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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: ReadIdleTimeout/PingTimeout not exposed if configured through http package #40201
Comments
And maybe @caesarxuchao if I can notify him at all this way. |
@fraenkel is the go-to guy for HTTP2. |
I created golang/net#74 but it was too late to get into 1.15. |
FWIW, in the test I added in golang/net#74, I used the |
In prometheus/common, x/net/http2 is vendored so I could easily "hack" the field in there. At least we have somewhat good confidence it resolves our Prometheus issues now. I indeed missed golang/net#74 when searching for a solution. Since at least Prometheus seems to actually vendor the code, we might be fine over there as soon as your PR is merged (they pin some very recent master commit, anyway). |
Do you know if using ForceAttemptHTTP2 (go 1.13+) instead of http2.ConfigureTransport would solve that? |
@roidelapluie Unfortunately, the h2 transport is not exposed by Lines 262 to 266 in fa98f46
So basically, it's impossible to directly manipulate the h2 transport out of net/http package. @JensErat is right. Currently no options is provided for upgrading h1 to h2. We'd better make it available ASAP. It really happens rarely but leads to disaster if you suddenly knock into it. See #39750 Lines 6632 to 6645 in fa98f46
|
We can confirm this resolves our Prometheus and Kubernetes issues (and thus likely the issues of lots of others, some might not even be aware of this). @brian-brazil from Prometheus already proposed the health check should be default anyway:
And I pretty much agree with him. This is something most applications will mess up. Lots of admin and developer days lost in debugging a hard to trace down issue. If I have long-lasting connections, those should be robust against network failures. Could this be considered a breaking change or just a fix? Issues with broken servers that cannot handle whatever http2 calls are sent to run the ping? A golang debug variable to set the value might also help in either case (force-enable or force-disable). |
Change https://golang.org/cl/236498 mentions this issue: |
Change https://golang.org/cl/264017 mentions this issue: |
There are several kubernetes bugs [0,1,2] involving connection problems that seem related to the Go net/http2 library, where the stream state and connection state can get out of sync. This can manifest as a kubelet issue, where the node status gets stuck in a NotReady state, but can also happen elsewhere. In newer versions of the Go libraries some issues are fixed [3,4], but the fixes are not present in k8s 1.18. This change disables http2 in kube-apiserver and webhook-apiserver. This should be sufficient to avoid the majority of the issues, as disabling on one side of the connection is enough, and apiserver is generally either the client or the server. 0: kubernetes/kubernetes#87615 1: kubernetes/kubernetes#80313 2: kubernetes/client-go#374 3: golang/go#40423 4: golang/go#40201 Change-Id: Id693a7201acffccbc4b3db8f4e4b96290fd50288
Given that golang/go#39337 and golang/go#40201 are fixed: - We now have a function to configure HTTP/2 transport, therefore we have a "ping" every 5 minutes on the line if not traffic is doing on - Dead HTTP/2 connections will be removed from the pool Signed-off-by: Julien Pivotto <roidelapluie@inuits.eu>
The ConfigureTransport function doesn't provide any way to get at the http2 Transport it creates, making it impossible to configure transport parameters such as ReadIdleTimeout. Add a ConfigureTransports function which returns the http2 Transport. The very similar names are unfortunate, but they'll sort next to each other in godoc and the pluralized ConfigureTransports hints at its purpose: it lets you configure both the http and http2 transports. Fixes golang/go#40201. Updates golang/go#41721. Change-Id: I97aa345f369f49462c41d3f60d35660c06c51287 Reviewed-on: https://go-review.googlesource.com/c/net/+/264017 Trust: Damien Neil <dneil@google.com> Trust: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Damien Neil <dneil@google.com> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes, following code on golang/net master branch.
What operating system and processor architecture are you using (
go env
)?not relevant
What did you do?
golang/net#55 brought a new feature in golang's http2 implementation that allows early detection of broken network connections. Setting this seems to resolve potentially several rare issues we're facing in production every now and then.
Now, most clients use the (I think also recommended?) way to instantiate an
http.Transport
, which is then "upgraded" to http2 capabilities. For example, in prometheus/common:or they set
Transport.ForceAttemptHTTP2 = true
.Both ways entirely hide the http2 transport, and I do not see a way to configure
http2.Transport.ReadIdleTimeout
/http2.Transport.PingTimeout
.This also seems to affect
k8s.io/apimachinery/pkg/util/net/http.go
, where this golang feature is best bet so far to resolve kubernetes/kubernetes#87615 (it seems to me golang/net#55 was specifically build because of the Kubernetes issue). golang/net#74 proposes an interface to set those values and would resolve this issue.What did you expect to see?
A possibility to configure
http2.Transport
fromhttp.Transport
where needed, for example by passing in anhttp2.Transport
into theConfigureTransport
function?What did you see instead?
No way to configure
http2.Transport
settings.The text was updated successfully, but these errors were encountered: