spring-boottomcathttp2keep-alive

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


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?


Solution

  • 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.