【问题标题】:How do I convey Keep-alive metadata when the HTTP/2 protocol is used?使用 HTTP/2 协议时如何传达 Keep-alive 元数据?
【发布时间】:2022-01-15 15:39:26
【问题描述】:

我有一个 angular Web 应用程序,它使用 Spring Boot 并在后端嵌入了 tomcat 服务器。我想让已建立的 http 连接保持更长时间,以提高后续 http 请求的响应时间。使用http/1.1,浏览器被告知通过将Connection: Keep-AliveKeep-Alive: timeout=5, max=1000 之类的东西添加到response header 来保持http 连接。但是,特定于连接的标头字段,例如 Connection 和 Keep-Alive are prohibited in HTTP/2。因此,Chrome 和 Firefox 在 HTTP/2 响应中会忽略它们。对于 HTTP/2,特定于连接的元数据应该是 conveyed by other means

我在任何地方都找不到那些“其他手段”应该是什么。我也找不到任何地方如何配置嵌入式 Tomcat 9 服务器以将 Keep-alive 元数据添加到 HTTP/2 响应。这就是tomcat现在的配置方式:

@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);
        }
    });
}

但如果我想使用HTTP/2,这些设置将不起作用。有什么想法吗?

【问题讨论】:

    标签: spring-boot tomcat http2 keep-alive


    【解决方案1】:

    对于 http/1.1,浏览器被告知通过在响应标头中添加 Connection: Keep-Alive 和类似 Keep-Alive: timeout=5, max=1000 来保持 http 连接。

    实际上并非如此。从 HTTP/1.1 开始,Connection: Keep-Alive 标头默认为这种情况,除非明确设置为 Close。事实上,我们甚至有标头更多的是 HTTP/1.0 天的遗留问题,不需要设置。响应总是更能说明服务器将做什么,而不是对客户端的指示(“嘿,仅供参考,我将使用这些设置”)但它也总是有点毫无意义,因为服务器(和客户端)如果它想要也可以断开连接。如果一台服务器的 TCP 连接用完,它不应该真正保留未使用的旧连接,而不是接受一个新连接。

    但是,HTTP/2 中禁止连接特定的标头字段,例如 Connection 和 Keep-Alive。因此,Chrome 和 Firefox 在 HTTP/2 响应中会忽略它们。对于 HTTP/2,连接特定的元数据应该通过其他方式传达。

    我在任何地方都找不到那些“其他手段”应该是什么。我也找不到任何地方如何配置嵌入式 Tomcat 9 服务器以将 Keep-alive 元数据添加到 HTTP/2 响应。这就是tomcat现在的配置方式:

    与以前一样,HTTP/2 只是摆脱了相当无意义的标头,并假设您想保持它的活力。它在 HTTP/2 中也不太有意义,因为它用于多个请求和响应,而 HTTP/1.1 一次只用于一个,并且 keep-alive 是连接级别的设置。因此,如果 HTTP/2 请求可以指定 keep-alive: close,那么对于该连接上已经在进行中的其他请求意味着什么?同样,将其设置为 keep-alive 也暗示了 HTTP/2’s multiplexing 的本质。

    由客户端和服务器根据自己的逻辑和资源限制来决定何时最好地断开连接,尽管HTTP/2 spec does go on to say this later:

    HTTP/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. 这是什么意思?那个http连接不应该保持活动太久?现在我保持一个http连接15分钟。这会导致服务器很容易用完 tcp 连接吗?我想让连接保持这么长时间,因为这样浏览器就不必经常进行 https 握手。我还了解到,这种方法可以节省资金,因为需要传输的数据更少。
    • 如果你有足够的流量,那么你总是可以用完连接。这就是为什么保持活动应该依赖于资源(在客户端和服务器上)而不是仅仅要求它保持活动的连接。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-22
    • 2013-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多