SpringBoot中啟用和測試HTTP/2的幾種方法
前置條件
在開始之前,需要注意:
- JDK 版本:需要 JDK 9+(推薦 JDK 11 或 17)
- SSL 證書:HTTP/2 在瀏覽器中需要 HTTPS,所以需要 SSL 證書
方法一:使用內(nèi)置 Undertow 服務(wù)器(推薦)
Undertow 原生支持 HTTP/2,配置簡單,性能優(yōu)秀。
1. 添加依賴
<!-- pom.xml -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<!-- 排除默認(rèn)的 Tomcat -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 使用 Undertow 作為服務(wù)器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
</dependencies>
2. 生成 SSL 證書
首先創(chuàng)建一個(gè)自簽名證書(用于測試):
# 在項(xiàng)目根目錄執(zhí)行 keytool -genkey -alias spring-boot-http2 -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650 # 輸入信息(測試時(shí)都可以用默認(rèn)值): # 密碼:password # 姓名:localhost
3. 配置 application.yml
# application.yml
server:
port: 8443
ssl:
key-store: classpath:keystore.p12
key-store-password: password
key-store-type: PKCS12
key-alias: spring-boot-http2
# HTTP/2 配置
http2:
enabled: true
# Undertow 特定配置
undertow:
threads:
worker: 64
io: 4
4. 創(chuàng)建測試 Controller
// Http2DemoController.java
import org.springframework.web.bind.annotation.*;
import java.util.*;
import java.util.stream.LongStream;
@RestController
@RequestMapping("/api")
public class Http2DemoController {
// 普通接口
@GetMapping("/hello")
public Map<String, String> hello() {
return Map.of(
"message", "Hello HTTP/2!",
"timestamp", new Date().toString(),
"protocol", "HTTP/2 with Undertow"
);
}
// 模擬大量數(shù)據(jù)返回,展示 HTTP/2 的多路復(fù)用優(yōu)勢
@GetMapping("/large-data")
public Map<String, Object> getLargeData() {
List<Map<String, Object>> data = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
data.add(Map.of(
"id", i,
"name", "Item " + i,
"value", Math.random() * 1000,
"timestamp", System.currentTimeMillis() + i
));
}
return Map.of(
"items", data,
"total", data.size(),
"server", "Undertow with HTTP/2"
);
}
// 計(jì)算密集型任務(wù)
@GetMapping("/calculate")
public Map<String, Object> calculate() {
long startTime = System.currentTimeMillis();
// 模擬計(jì)算任務(wù)
long sum = LongStream.range(0, 10_000_000)
.parallel()
.sum();
long endTime = System.currentTimeMillis();
return Map.of(
"result", sum,
"calculationTime", endTime - startTime + "ms",
"protocol", "HTTP/2"
);
}
}
5. 創(chuàng)建主應(yīng)用類
// SpringBootHttp2Application.java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import io.undertow.UndertowOptions;
@SpringBootApplication
public class SpringBootHttp2Application {
public static void main(String[] args) {
SpringApplication.run(SpringBootHttp2Application.class, args);
}
@Bean
public UndertowServletWebServerFactory undertowServletWebServerFactory() {
UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory();
factory.addBuilderCustomizers(builder -> {
// 啟用 HTTP/2
builder.setServerOption(UndertowOptions.ENABLE_HTTP2, true);
// 其他優(yōu)化配置
builder.setServerOption(UndertowOptions.ALWAYS_SET_KEEP_ALIVE, false);
builder.setServerOption(UndertowOptions.ALWAYS_SET_DATE, true);
});
return factory;
}
}
方法二:使用 Tomcat(需要 ALPN)
Tomcat 9+ 也支持 HTTP/2,但配置稍復(fù)雜。
1. 依賴配置(使用 Tomcat)
<!-- pom.xml -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 對于 JDK 9+,需要包含 tomcat-embed-core -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
</dependency>
</dependencies>
2. Tomcat 配置
# application.yml
server:
port: 8443
ssl:
key-store: classpath:keystore.p12
key-store-password: password
key-store-type: PKCS12
key-alias: spring-boot-http2
http2:
enabled: true
# Tomcat 特定配置
tomcat:
max-threads: 200
min-spare-threads: 10
測試 HTTP/2
1. 啟動(dòng)應(yīng)用
啟動(dòng) Spring Boot 應(yīng)用后,你應(yīng)該看到類似日志:
Tomcat started on port(s): 8443 (https) with context path '' // 或 Undertow started on port(s): 8443 (https) with context path ''
2. 使用 curl 測試
# 測試 HTTP/2 curl -k -I --http2 https://localhost:8443/api/hello # 正常請求 curl -k --http2 https://localhost:8443/api/hello
3. 瀏覽器測試
- 訪問
https://localhost:8443/api/hello - 由于是自簽名證書,瀏覽器會(huì)顯示不安全警告,選擇"繼續(xù)前往"
- 打開開發(fā)者工具 → Network 標(biāo)簽
- 刷新頁面,在 Protocol 列應(yīng)該看到
h2(HTTP/2)
4. 創(chuàng)建測試頁面展示多路復(fù)用優(yōu)勢
// 添加這個(gè) Controller 來演示多請求并發(fā)
@Controller
class DemoPageController {
@GetMapping("/")
public String index() {
return "index";
}
}
在 src/main/resources/templates/index.html:
<!DOCTYPE html>
<html>
<head>
<title>HTTP/2 Demo</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<h1>Spring Boot HTTP/2 演示</h1>
<button onclick="testSequential()">順序請求測試 (模擬 HTTP/1.1)</button>
<button onclick="testParallel()">并行請求測試 (HTTP/2 多路復(fù)用)</button>
<div id="result"></div>
<script>
async function testSequential() {
const start = Date.now();
const result = $('#result');
result.html('測試中...');
// 順序請求
for (let i = 0; i < 10; i++) {
await fetch('/api/calculate')
.then(r => r.json());
}
const duration = Date.now() - start;
result.html(`順序請求完成: ${duration}ms`);
}
function testParallel() {
const start = Date.now();
const result = $('#result');
result.html('測試中...');
// 并行請求
const promises = [];
for (let i = 0; i < 10; i++) {
promises.push(fetch('/api/calculate').then(r => r.json()));
}
Promise.all(promises).then(() => {
const duration = Date.now() - start;
result.html(`并行請求完成: ${duration}ms (HTTP/2 多路復(fù)用優(yōu)勢)`);
});
}
</script>
</body>
</html>
完整配置示例(生產(chǎn)建議)
對于生產(chǎn)環(huán)境,建議使用如下配置:
# application-prod.yml
server:
port: 443
ssl:
key-store: /etc/ssl/certs/keystore.p12
key-store-password: ${KEYSTORE_PASSWORD}
key-store-type: PKCS12
key-alias: my-production-cert
http2:
enabled: true
compression:
enabled: true
mime-types: text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json
min-response-size: 1024
servlet:
session:
timeout: 30m
# Undertow 生產(chǎn)配置
undertow:
threads:
worker: 100 # 根據(jù) CPU 核心數(shù)調(diào)整
io: 8 # 通常為核心數(shù)
# 日志配置
logging:
level:
org.springframework: INFO
io.undertow: WARN
總結(jié)
- 推薦使用 Undertow:配置簡單,性能優(yōu)秀,原生支持 HTTP/2
- 必須配置 SSL:HTTP/2 在瀏覽器中需要 HTTPS
- 多路復(fù)用優(yōu)勢:在需要大量并發(fā)請求的場景下,HTTP/2 性能提升明顯
- 向后兼容:HTTP/2 不改變 HTTP 語義,現(xiàn)有代碼無需修改
這個(gè)示例展示了如何在 Spring Boot 中啟用和測試 HTTP/2,你可以直接運(yùn)行來體驗(yàn) HTTP/2 的性能優(yōu)勢。
以上就是SpringBoot中啟用和測試HTTP/2代碼示例的幾種方法的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot啟用和測試HTTP/2代碼的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringBoot?注解?@AutoConfiguration?在?2.7?版本中被新增的使用方法詳解
這篇文章主要介紹了SpringBoot?注解?@AutoConfiguration?在?2.7?版本中被新增(使用方法),本文給大家介紹的非常詳細(xì),需要的朋友可以參考下2024-09-09
SpringBoot重寫addResourceHandlers映射文件路徑方式
這篇文章主要介紹了SpringBoot重寫addResourceHandlers映射文件路徑方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02
解決Spring?Boot應(yīng)用打包后文件訪問問題
在Spring Boot項(xiàng)目的開發(fā)過程中,一個(gè)常見的挑戰(zhàn)是如何有效地訪問和操作資源文件,本文就來介紹一下解決Spring?Boot應(yīng)用打包后文件訪問問題,感興趣的可以了解一下2024-01-01
Spring整合Mybatis使用<context:property-placeholder>時(shí)的坑
這篇文章主要介紹了Spring整合Mybatis使用<context:property-placeholder>時(shí)的坑 的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06

