How do I convey Keep-alive metadata when the HTTP/2 protocol is used?
Asked Answered
H

1

0

I have an angular web application that uses Spring boot with an embedded tomcat server in the backend. I want to keep established http connections alive longer to improve the response time of subsequent http requests. With http/1.1 a browser is told to keep the http connection alive by adding Connection: Keep-Alive and something like Keep-Alive: timeout=5, max=1000 to the response header. However connection-specific header fields such as Connection and Keep-Alive are prohibited in HTTP/2. Because of that Chrome and Firefox ignore them in HTTP/2 responses. With HTTP/2, connection-specific metadata should be conveyed by other means.

I can't find anywhere what those 'other means' should be though. Nor can i find anywhere how to configure an embedded Tomcat 9 server to add Keep-alive meta data to a HTTP/2 response. This is how tomcat is configured right now:

@Bean
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> tomcatCustomizer() {
    return (tomcat) -> tomcat.addConnectorCustomizers((connector) -> {
        if (connector.getProtocolHandler() instanceof AbstractHttp11Protocol) {
            AbstractHttp11Protocol<?> protocolHandler = (AbstractHttp11Protocol<?>) connector
                    .getProtocolHandler();
            protocolHandler.setDisableUploadTimeout(false);
            protocolHandler.setConnectionUploadTimeout(5000);
            protocolHandler.setKeepAliveTimeout(4000);
            protocolHandler.setMaxKeepAliveRequests(200);
            protocolHandler.setUseKeepAliveResponseHeader(true);
        }
    });
}

But these settings aren't going to work if i want to use HTTP/2. Any ideas?

Herwick answered 15/1, 2022 at 4:14 Comment(0)
C
6

With http/1.1 a browser is told to keep the http connection alive by adding Connection: Keep-Alive and something like Keep-Alive: timeout=5, max=1000 to the response header.

That’s not actually true. Since HTTP/1.1 the Connection: Keep-Alive header is defaulted to be the case unless explicitly set to Close. The fact we even have the header is more a left over from HTTP/1.0 days and shouldn’t need to be set. The response has always been more informative of what the server will do rather than an instruction to the client (“hey, FYI I’m going to be using these settings”) but it was always kind of meaningless too since server (and client) could drop the connection if it wanted too. If a server is running out of TCP connections it shouldn’t really keep and old one that is not being used alive rather than accept a new one, in general.

However connection-specific header fields such as Connection and Keep-Alive are prohibited in HTTP/2. Because of that Chrome and Firefox ignore them in HTTP/2 responses. With HTTP/2, connection-specific metadata should be conveyed by other means.

I can't find anywhere what those 'other means' should be though. Nor can i find anywhere how to configure an embedded Tomcat 9 server to add Keep-alive meta data to a HTTP/2 response. This is how tomcat is configured right now:

In the same way as previous, HTTP/2 just got rid of the rather pointless header and assumed you want to keep it alive. It also made less sense in HTTP/2 as it’s used for multiple requests and responses whereas HTTP/1.1 is only used for one at a time and keep-alive is a connection-level setting. So if an HTTP/2 request could specific a keep-alive: close what would that mean for other requests on that connection that are already in-flight? And similarly setting it to keep-alive is implied by the very nature of HTTP/2’s multiplexing.

It’s up to the client and server to decide when best to drop the connection, based on its own logic and resource constraints, though the HTTP/2 spec does go on to say this later:

HTTP/2 connections are persistent. For best performance, it is expected that clients will not close connections until it is determined that no further communication with a server is necessary (for example, when a user navigates away from a particular web page) or until the server closes the connection.

Cleora answered 15/1, 2022 at 7:39 Comment(2)
If a server is running out of TCP connections it shouldn’t really keep and old one that is not being used alive rather than accept a new one, in general. What do you mean by that? That http connections shouldn't be kept alive for too long? Right now I keep an http connection alive for 15 minutes. Would that cause the server to easily run out of tcp connections? I want to keep the connection alive for that long because that way the browser won't have to do a https handshake very often. I've also read that this approach will save me money because less data has to be transferred.Herwick
If you have enough traffic then you can always run out of connections. That’s why keep-alive should depend on resources (on client and server) rather than a connection just asking for it to be kept-alive.Cleora

© 2022 - 2024 — McMap. All rights reserved.