HTTP/1.1 长期以来一直是传递 HTTP 请求的主导协议,而 HTTP/2 则提供了更好的资源效率和更低的延迟。这是一项巨大的进步,对现代 Web 应用程序而言是一次重大升级。
要使用 HTTP/2 协议运行 Spring Boot 应用程序,我们必须在 Spring Boot 应用程序中启用 SSL 和 HTTP/2 设置。
HTTP/2是广泛使用的 HTTP/1.1 协议的后继者,它通过采用多路复用和头压缩等新功能来提高 Web 性能。
在本教程中,我们将介绍如何配置 Spring Boot 应用程序以在嵌入式Tomcat服务器上启用 HTTP/2。
HTTP/2
超文本传输协议 (HTTP) 是一种用于获取互联网资源的应用程序协议。HTTP/1.1 于 1997 年 1 月发布,二十多年来一直服务于大多数网络。此版本确定了在某些情况下导致性能缓慢的问题。
HTTP/2通过以下特点克服了 HTTP/1.1 中的性能问题:
- 多路复用- HTTP/1.1 使用多个连接发送多个请求;多路复用允许通过单个连接发送请求,从而减少资源消耗和延迟
- 压缩报头——如果不进行压缩,由于 TCP 启动缓慢,通常需要多次往返才能发送报头;压缩报头可以保证报头在更少的往返中发送,并且大多数情况下只需一次往返即可
- 二进制- HTTP/2 以二进制格式发送数据,以减少解析开销,并且消息大小比使用文本编码数据的 HTTP/1.1 更小
先决条件
HTTP/2 可以 以明文或 TLS 方式运行。大多数网络浏览器不支持明文 HTTP/2,因此我们建议通过 TLS 运行。我们首先在嵌入式网络服务器上启用 SSL。
让我们生成一个密钥库来存储用于 SSL/TLS 的密钥和证书,并将其放在嵌入式 Tomcat 中。我们将在控制台中运行以下keytool来生成它:
$ keytool -genkeypair -alias http2-alias -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore keystore.p12 -validity 3650 |
keytool将要求我们输入密码,稍后我们需要将其添加到 Spring Boot 配置中。完成此过程后,该工具将生成keystore.p12文件。我们将此文件复制到Spring Boot 应用程序下的资源文件夹中。
现在,我们必须向application.yml添加以下属性以在嵌入式 Tomcat 中启用 HTTPS:
server: |
检查响应中的 HTTP 协议版本
默认情况下,Spring Boot 嵌入式 Tomcat 不会启用 HTTP/2 协议来处理请求。让我们创建一个简单的 Spring Boot REST 端点来验证它:
@RestController |
该端点只是接受请求参数消息并将其在响应主体中发回。
一旦启动应用程序,我们就可以在控制台中使用–http2参数执行以下curl命令,以通过 HTTP/2 调用端点:
$ curl -I --http2 http://localhost:8080/http2/echo?message=hello |
-I参数向我们显示了其他信息,例如响应中的 HTTP 协议版本。从打印输出中,我们可以看到应用程序返回:
HTTP/1.1 200
或者,我们可以使用Postman来验证协议版本。它从 11.8 版开始支持 HTTP/2 协议,其中发送 HTTP 请求的协议版本仍为默认的 HTTP/1.1。我们可以在设置选项卡中更改协议版本:
一旦我们发送请求,我们就可以从 Postman 控制台中的原始日志中找到 HTTP 协议版本。
即使我们以 HTTP/2 发送请求,curl 和 Postman 都会返回 HTTP/1.1 响应。
在 Spring Boot 中启用 HTTP/2
现在,让我们在嵌入式 Tomcat 中启用 HTTP/2。有两种方法可以在 Spring Boot 应用程序中启用 HTTP/2。
第一种方法
是通过定义一个配置类将Http2Protocol类添加到 Tomcat HTTP 连接器:
@Configuration |
该配置类定制了嵌入式 Tomcat 服务器,并通过向HTTP 连接器添加Http2Protocol升级来启用 HTTP/2 支持。
此配置除了现有的运行带 SSL 的 HTTP/2 的端口 8443 之外,还打开了一个在 HTTP 上运行的附加端口 8080。如果我们不想公开附加端口,我们可以使用替代方法来启用 HTTP/2。
第二个就更简单了
我们只需要在application.yml 中将属性server.http2.enabled标记为 true 即可:
server: |
应用其中任一个后重新启动应用程序,我们就可以执行相同的curl命令来查询 REST 端点;我们将收到以下响应,表明 HTTP/2 已启用:
HTTP/2 200
如果我们再次向 Postman 发送请求,我们将看到响应。