在 Spring Boot 中使用 Tomcat 啟用 HTTP2
1. 概述
HTTP/2 是廣泛使用的 HTTP/1.1 協定的後繼者,它透過採用多路復用和頭壓縮等新功能來提高 Web 效能。
在本教程中,我們將介紹如何設定 Spring Boot 應用程式以在嵌入式 Tomcat 伺服器上啟用 HTTP/2。
2.HTTP/2
超文本傳輸協定(HTTP)是一種用於獲取網際網路上資源的應用協定。 HTTP/1.1 於 1997 年 1 月發布,並且已經為大多數網路服務了二十多年。此版本發現了在某些情況下導致效能緩慢的問題。
HTTP/2 透過以下特點克服了 HTTP/1.1 中的效能問題:
- 多路復用-HTTP/1.1 使用多個連線發送多個請求;多路復用允許透過單一連線發送請求,從而減少資源消耗和延遲
- 壓縮報頭-如果不進行壓縮,由於 TCP 啟動緩慢,通常需要多次往返才能發送報頭;壓縮報頭可以保證報頭在更少的往返中發送,並且大多數情況下在一次往返內
- 二進位- HTTP/2 以二進位格式發送數據,以減少解析開銷,且訊息大小比使用文字編碼資料的 HTTP/1.1 更小
3. 先決條件
HTTP/2 可以**以明文或 TLS 運作。**大多數網頁瀏覽器不支援明文 HTTP/2,因此我們建議透過 TLS 運行它。我們首先在嵌入式 Web 伺服器上啟用 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 應用程式下的resources
資料夾。
現在,我們必須為application.yml
新增以下屬性以在嵌入式 Tomcat 中啟用 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 協定來處理請求。讓我們建立一個簡單的 Spring Boot REST 端點來驗證它:
@RestController
public class Http2Controller {
@GetMapping("/http2/echo")
public String getChatbotResponse(@RequestParam String message) {
return message;
}
}
該端點只是接受請求參數message
並將其在回應主體中發回。
一旦啟動應用程序,我們就可以在控制台中使用–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 回應。
5. 在 Spring Boot 中啟用 HTTP/2
現在,讓我們在嵌入式 Tomcat 中啟用 HTTP/2。有兩種方法可以在 Spring Boot 應用程式中啟用 HTTP/2。
第一種方法是透過定義一個配置類別將Http2Protocol
類別新增到 Tomcat HTTP 連接器:
@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);
};
}
}
此組態類別自訂了嵌入式 Tomcat 伺服器,並透過向 HTTP 連接器新增Http2Protocol
升級來啟用 HTTP/2 支援。
此配置除了現有的運行帶有 SSL 的 HTTP/2 的連接埠 8443 之外,還開啟了在 HTTP 上執行的附加連接埠 8080。如果我們不想公開額外的端口,我們可以使用替代方法來啟用 HTTP/2。
第二個就更簡單了。我們只需要在application.yml
屬性server.http2.enabled
標記為 true :
server:
http2:
enabled: true
應用其中任一個後重新啟動應用程序,我們就可以執行相同的curl
命令來查詢 REST 端點;我們將收到以下回應,表示 HTTP/2 已啟用:
HTTP/2 200
如果我們再次向 Postman 發送請求,我們將看到以下回應:
6. 結論
HTTP/1.1 長期以來一直是傳遞 HTTP 請求的主要協議,而 HTTP/2 則提供了更好的資源效率並降低了延遲。這是一個巨大的進步,對現代網路應用程式來說是一個重大的升級。
要使用 HTTP/2 協定執行 Spring Boot 應用程序,我們必須在 Spring Boot 應用程式中啟用 SSL 和 HTTP/2 設定。
與往常一樣,完整的範例可以在 GitHub 上找到。