1. 概述

HTTP/2 是广泛使用的 HTTP/1.1 协议的继任者,通过引入多路复用和头部压缩等新功能,显著提升了 Web 性能。本教程将介绍如何在 Spring Boot 应用中配置嵌入式 Tomcat 服务器来启用 HTTP/2。

2. HTTP/2

超文本传输协议(HTTP)是用于获取互联网资源的应用层协议。HTTP/1.1 发布于1997年,在过去二十多年中支撑了大部分 Web 服务。但该版本在某些场景下存在性能瓶颈。

HTTP/2 通过以下特性解决了 HTTP/1.1 的性能问题:

  • 多路复用 - HTTP/1.1 需要多个连接发送多个请求;多路复用允许在单个连接上发送请求,减少资源消耗和延迟
  • 头部压缩 - 未压缩时,由于 TCP 慢启动机制,发送头部常需多次往返;压缩后可确保头部在更少往返次数内完成传输(通常一次即可)
  • 二进制传输 - HTTP/2 使用二进制格式传输数据,相比 HTTP/1.1 的文本编码,减少了解析开销和消息体积

3. 前提条件

⚠️ HTTP/2 可运行于明文或 TLS 加密通道。但大多数浏览器不支持明文 HTTP/2,因此建议通过 TLS 运行。我们首先需要在嵌入式 Web 服务器上启用 SSL。

使用 keytool 生成用于 SSL/TLS 的密钥库(keystore),并放置到嵌入式 Tomcat 中:

$ keytool -genkeypair -alias http2-alias -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore keystore.p12 -validity 3650

执行时会要求设置密码(后续配置需使用)。完成后将生成的 keystore.p12 文件复制到 Spring Boot 应用的 resources 目录。

application.yml 中添加以下配置启用 HTTPS:

server:
  ssl:
    enabled: true
    key-store: classpath:keystore.p12
    key-store-password: <your-password>
    key-store-type: PKCS12
    key-alias: http2-alias

4. 检查响应中的HTTP协议版本

默认情况下,Spring Boot 嵌入式 Tomcat 不会启用 HTTP/2 协议。创建一个简单的 REST 接口验证:

@RestController
public class Http2Controller {
    @GetMapping("/http2/echo")
    public String getChatbotResponse(@RequestParam String message) {
        return message;
    }
}

该接口接收 message 参数并原样返回。

启动应用后,使用带 --http2 参数的 curl 命令测试:

$ curl -I --http2 http://localhost:8080/http2/echo?message=hello

-I 参数会显示额外信息(如 HTTP 协议版本)。输出显示:

HTTP/1.1 200

也可使用 Postman 验证(v11.8+ 支持 HTTP/2)。在设置中修改协议版本: postman http2 setting

发送请求后,在 Postman 控制台的原始日志中查看协议版本: postman http2 response

即使使用 HTTP/2 发送请求,curl 和 Postman 均返回 HTTP/1.1 响应。

5. 在Spring Boot中启用HTTP/2

有两种方式在 Spring Boot 中启用 HTTP/2:

方式一:通过配置类添加 Http2Protocol

@Configuration
public class Http2Config {
    @Bean
    public WebServerFactoryCustomizer<TomcatServletWebServerFactory> getWebServerFactoryCustomizer() {
        return factory -> {
            Connector httpConnector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
            httpConnector.setPort(8080);
            factory.addConnectorCustomizers(connector -> connector.addUpgradeProtocol(new Http2Protocol()));
            factory.addAdditionalTomcatConnectors(httpConnector);
        };
    }
}

此配置通过向 HTTP 连接器添加 Http2Protocol 升级来启用 HTTP/2。但会额外开放 8080 端口(HTTP),而 8443 端口运行 HTTPS + HTTP/2。

方式二:简单粗暴的配置属性

server:
  http2:
    enabled: true

应用任一配置重启后,再次执行 curl 命令:

HTTP/2 200

Postman 响应也显示 HTTP/2: postman http2 response

6. 结论

HTTP/1.1 长期主导 HTTP 请求传输,而 HTTP/2 提供了更优的资源效率和更低延迟,是现代 Web 应用的重大升级。

💡 要在 Spring Boot 中运行 HTTP/2,必须同时启用 SSL 和 HTTP/2 设置。踩坑提醒:浏览器不支持明文 HTTP/2,务必配置 TLS!


原始标题:Enable HTTP2 with Tomcat in Spring Boot | Baeldung