前置条件
在开始之前,需要注意:
- jdk 版本:需要 jdk 9+(推荐 jdk 11 或 17)
- ssl 证书:http/2 在浏览器中需要 https,所以需要 ssl 证书
方法一:使用内置 undertow 服务器(推荐)
undertow 原生支持 http/2,配置简单,性能优秀。
1. 添加依赖
<!-- pom.xml -->
<dependencies>
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-web</artifactid>
<exclusions>
<!-- 排除默认的 tomcat -->
<exclusion>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-tomcat</artifactid>
</exclusion>
</exclusions>
</dependency>
<!-- 使用 undertow 作为服务器 -->
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-undertow</artifactid>
</dependency>
</dependencies>
2. 生成 ssl 证书
首先创建一个自签名证书(用于测试):
# 在项目根目录执行 keytool -genkey -alias spring-boot-http2 -storetype pkcs12 -keyalg rsa -keysize 2048 -keystore keystore.p12 -validity 3650 # 输入信息(测试时都可以用默认值): # 密码: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. 创建测试 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"
);
}
// 模拟大量数据返回,展示 http/2 的多路复用优势
@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"
);
}
// 计算密集型任务
@getmapping("/calculate")
public map<string, object> calculate() {
long starttime = system.currenttimemillis();
// 模拟计算任务
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. 创建主应用类
// 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);
// 其他优化配置
builder.setserveroption(undertowoptions.always_set_keep_alive, false);
builder.setserveroption(undertowoptions.always_set_date, true);
});
return factory;
}
}
方法二:使用 tomcat(需要 alpn)
tomcat 9+ 也支持 http/2,但配置稍复杂。
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. 启动应用
启动 spring boot 应用后,你应该看到类似日志:
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 - 由于是自签名证书,浏览器会显示不安全警告,选择"继续前往"
- 打开开发者工具 → network 标签
- 刷新页面,在 protocol 列应该看到
h2(http/2)
4. 创建测试页面展示多路复用优势
// 添加这个 controller 来演示多请求并发
@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 多路复用)</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 多路复用优势)`);
});
}
</script>
</body>
</html>
完整配置示例(生产建议)
对于生产环境,建议使用如下配置:
# 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 生产配置
undertow:
threads:
worker: 100 # 根据 cpu 核心数调整
io: 8 # 通常为核心数
# 日志配置
logging:
level:
org.springframework: info
io.undertow: warn
总结
- 推荐使用 undertow:配置简单,性能优秀,原生支持 http/2
- 必须配置 ssl:http/2 在浏览器中需要 https
- 多路复用优势:在需要大量并发请求的场景下,http/2 性能提升明显
- 向后兼容:http/2 不改变 http 语义,现有代码无需修改
这个示例展示了如何在 spring boot 中启用和测试 http/2,你可以直接运行来体验 http/2 的性能优势。
以上就是springboot中启用和测试http/2代码示例的几种方法的详细内容,更多关于springboot启用和测试http/2代码的资料请关注代码网其它相关文章!
发表评论