Spring Boot集成Jetty、Tomcat或Undertow及支持HTTP/2协议

embedded/2025/2/28 12:38:23/

目录

一、常用Web服务器

1、Tomcat

2、Jetty

3、Undertow

二、什么是HTTP/2协议

1、定义

2、特性

3、优点

4、与HTTP/1.1的区别

三、集成Web服务器并开启HTTP/2协议

1、生成证书

2、新建springboot项目

3、集成Web服务器

3.1 集成Tomcat

3.2 集成Jetty

3.3 集成Undertow


一、常用Web服务器

在Spring Boot应用中,选择合适的Web服务器是至关重要的。常见的Web服务器有Jetty、Tomcat和Undertow。它们各自具有不同的特点和优势,下面将进行详细的比较。

1、Tomcat

Tomcat是Apache基金会下的一个开源项目,是一个实现了Java Servlet和JavaServer Pages (JSP)技术的Web服务器。它支持最新的Java EE标准,并提供了丰富的特性,如会话管理、安全性和集群部署等。Tomcat在大型企业级应用中广泛使用。

2、Jetty

Jetty是一个轻量级的Java Web服务器,具有高效的事件处理机制和多线程模型。它支持多种协议,如HTTP/2、WebSocket和HTTP/1.1。Jetty的启动速度快,适用于小型到中型应用。

3、Undertow

Undertow是WildFly应用服务器中的嵌入式Web服务器,后来被独立出来成为了一个单独的项目。它是一个高性能的异步事件驱动的Web服务器,支持HTTP/2、WebSocket和Java Servlet 4.0。Undertow具有低延迟、高吞吐量和优秀的扩展性。对于大多数Spring Boot应用来说,Undertow是一个很好的选择。

总结:

  • Jetty更轻量级。这是相对Tomcat而言的。由于Tomcat除遵循JavaServlet规范之外,自身还扩展大量JEE特性以满足企业级应用的需求,所以Tomcat是较重量级的,而且配置较Jetty复杂许多。并且Jetty更灵活,体现在其可插拔性和可扩展性,更易于开发者对Jetty本身进行二次开发,定制一个适合自身需求的WebServer。
  • 在高并发系统中,Tomcat 相对来说比较弱。在相同的机器配置下,模拟相等的请求数,Undertow 在性能和内存使用方面都是最优的。并且 Undertow 新版本默认使用持久连接,这将会进一步提高它的并发吞吐能力。所以,如果是高并发的业务系统,Undertow 是最佳选择。

二、什么是HTTP/2协议

HTTP/2是HTTP协议的第二个主要版本,于2015年发布,用于在Web服务器和客户端之间传输数据。以下是关于HTTP/2的详细介绍:

1、定义

HTTP/2(超文本传输协议第2版,最初命名为HTTP 2.0),简称为h2(基于TLS/1.2或以上版本的加密连接)或h2c(非加密连接)。它是HTTP协议自1999年HTTP 1.1的改进版RFC发布后的首个更新,主要基于SPDY协议。多数主流浏览器已经在2015年底支持了该协议。

2、特性

  1. 多路复用‌:HTTP/2允许同时发送多个请求和响应,而不是像HTTP/1.1一样只能一个一个地处理。这样可以减少延迟,提高效率,提高网络吞吐量。
  2. 二进制传输‌:HTTP/2使用二进制协议,与HTTP/1.1使用的文本协议不同。二进制协议可以更快地解析,更有效地传输数据,减少了传输过程中的开销和延迟。
  3. 头部压缩‌:HTTP/2使用HPACK算法对HTTP头部进行压缩,减少了头部传输的数据量,从而减少了网络延迟。
  4. 服务器推送‌:HTTP/2支持服务器推送,允许服务器在客户端请求之前推送资源,以提高性能。
  5. 改进的安全性‌:HTTP/2默认使用TLS(Transport Layer Security)加密传输数据,提高了安全性。
  6. 兼容HTTP/1.1‌:HTTP/2可以与HTTP/1.1共存,服务器可以同时支持HTTP/1.1和HTTP/2。如果客户端不支持HTTP/2,服务器可以回退到HTTP/1.1。

3、优点

  1. 解析效率高‌:二进制数据更易于机器处理,提高了解析效率。
  2. 紧凑性好‌:减少了冗余字符和格式化问题,使得数据更加紧凑。
  3. 低错误率‌:避免了HTTP/1.1中容易因空格、大小写、换行符等问题导致的错误。
  4. 减少请求次数‌:服务器推送功能允许服务器在响应客户端请求时,提前发送额外的资源,减少了客户端的请求次数和等待时间。

4、与HTTP/1.1的区别

  1. 连接管理‌:HTTP/1.1中,每个请求都需要单独建立和维护连接;而HTTP/2允许同时在同一连接中发送多个请求和响应。
  2. 头部传输‌:HTTP/1.1中,头部字段需要在每个请求和响应中重复发送;而HTTP/2对头部进行了压缩,减少了重复的数据传输。
  3. 服务器推送‌:HTTP/1.1中,服务器无法主动推送额外的资源给客户端;而HTTP/2使服务器能够主动推送额外的资源给客户端。
  4. 安全性‌:HTTP/1.1中,加密是可选的;而HTTP/2默认使用TLS加密传输数据。

总的来说,HTTP/2在性能、安全性和可用性方面都有显著的改进,可以使Web应用更加快速、高效和可靠。

三、集成Web服务器并开启HTTP/2协议

1、生成证书

虽然HTTP/2理论上可以在非加密连接上使用,但实际上所有主流浏览器都要求HTTP/2必须基于TLS(HTTPS)。这意味着HTTP/2几乎总是与SSL/TLS一起使用。

keytool 是 Java Development Kit (JDK) 的一部分,用于管理密钥和证书。以下是一些常见的 keytool 命令示例,用于生成证书:

keytool -genkeypair -alias wisely -keyalg RSA -keysize 2048 -keystore keystore.jks -validity 365 -storepass pass1234 -keypass pass1234

  • -genkeypair: 生成密钥对。

  • -alias: 密钥的别名。

  • -keyalg: 密钥算法,这里使用 RSA。

  • -keysize: 密钥长度,2048 位是推荐的安全长度。

  • -keystore: 指定密钥库文件名。

  • -validity: 证书有效期,单位是天。

  • -storepass: 密钥库的密码。

  • -keypass: 密钥的密码。

>keytool -genkeypair -alias wisely -keyalg RSA -keysize 2048 -keystore keystore.jks -validity 365 -storepass pass1234 -keypass pass1234
您的名字与姓氏是什么?[Unknown]:  budong
您的组织单位名称是什么?[Unknown]:  budong   
您的组织名称是什么?[Unknown]:  budong
您所在的城市或区域名称是什么?[Unknown]:  hangzhou       
您所在的省/市/自治区名称是什么?[Unknown]:  zhejiang         
该单位的双字母国家/地区代码是什么?[Unknown]:  CN
CN=budong, OU=budong, O=budong, L=hangzhou, ST=zhejiang, C=CN是否正确?[否]:  y正在为以下对象生成 2,048 位RSA密钥对和自签名证书 (SHA256withRSA) (有效期为 365 天):CN=budong, OU=budong, O=budong, L=hangzhou, ST=zhejiang, C=CN

2、新建springboot项目

新建springboot项目,把生成的mykeystore.jks文件文件放在resources目录下。部分代码如下:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/test")
public class TestController {@RequestMapping("/hello")public String hello() {return "Hello Tomcat!";}
}

3、集成Web服务器

3.1 集成Tomcat

(1)配置pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>webserver</artifactId><version>1.0-SNAPSHOT</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.5.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies>
</project>

(2)配置application.yml

server:port: 8443servlet:context-path: /server1ssl:key-store: classpath:keystore.jkskey-store-password: pass1234key-store-type: JKSkey-alias: wiselykey-password: pass1234http2:enabled: true

(3)启动服务

服务启动后,在浏览器输入:https://127.0.0.1:8443/server1/test/hello

可以看到hello请求协议类型是h2,即HTTP/2。

https://i-blog.csdnimg.cn/direct/8b8351e7a046459bbae9a0c8101af298.png" width="1193" />

如果使用Google浏览器,Network默认不显示Protocol,在表头这一行右键,选择需要显示的列。

https://i-blog.csdnimg.cn/direct/581347bbe9934d75baf3a1bd3500628d.png" width="1117" />

3.2 集成Jetty

(1)配置pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>webserver2</artifactId><version>1.0-SNAPSHOT</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.5.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId></exclusion></exclusions></dependency><!-- Jetty Starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jetty</artifactId></dependency><!-- HTTP/2 相关依赖 --><dependency><groupId>org.eclipse.jetty.http2</groupId><artifactId>http2-server</artifactId></dependency><!--<dependency><groupId>org.eclipse.jetty</groupId><artifactId>jetty-alpn-server</artifactId></dependency>--><dependency><groupId>org.eclipse.jetty</groupId><artifactId>jetty-alpn-java-server</artifactId></dependency><!-- 可选依赖,根据需求添加 --><!-- <dependency><groupId>org.eclipse.jetty.http2</groupId><artifactId>http2-client</artifactId></dependency><dependency><groupId>org.eclipse.jetty</groupId><artifactId>jetty-alpn-client</artifactId></dependency> --></dependencies>
</project>

(2)配置application.yml

server:port: 8443servlet:context-path: /server2ssl:key-store: classpath:keystore.jkskey-store-password: pass1234key-store-type: JKSkey-alias: wiselykey-password: pass1234http2:enabled: truejetty:threads:acceptors: 4selectors: 8

(3)启动服务

服务启动后,查看日志输出,打印出(ssl, alpn, h2, http/1.1),则表示h2启用成功。

https://i-blog.csdnimg.cn/direct/5c2cb2a9dfd842799d6ca2680fb3a070.png" width="1078" />

在浏览器输入:https://127.0.0.1:8443/server2/test/hello

可以看到hello请求协议类型是h2,即HTTP/2。

https://i-blog.csdnimg.cn/direct/fa8c444a793945f0af07016de3476705.png" width="1106" />

(4)高级配置

除了可以在配置文件中配置Jetty参数外,还可以在配置类中通过编程方式进行配置。例如,你可以设置Jetty的线程池大小、SSL配置等。

import org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory;
import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory;
import org.eclipse.jetty.server.*;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class JettyConfig {@Bean@Autowiredpublic ConfigurableServletWebServerFactory configurableServletWebServerFactory(ServerProperties serverProperties) {JettyServletWebServerFactory factory = new JettyServletWebServerFactory();factory.addServerCustomizers(server -> {if (serverProperties.getSsl() != null && serverProperties.getSsl().isEnabled()) {ServerConnector connector = (ServerConnector) server.getConnectors()[0];int port = connector.getPort();SslContextFactory sslContextFactory = connector.getConnectionFactory(SslConnectionFactory.class).getSslContextFactory();HttpConfiguration httpConfiguration = connector.getConnectionFactory(HttpConnectionFactory.class).getHttpConfiguration();// 配置SSL上下文工厂和HTTP/2连接工厂ConnectionFactory[] connectionFactories = new ConnectionFactory[]{new SslConnectionFactory(sslContextFactory, "alpn"),new ALPNServerConnectionFactory("h2", "h2-17", "h2-16", "h2-15", "h2-14"),new HTTP2ServerConnectionFactory(httpConfiguration)};// 创建新的ServerConnector并设置到服务器上ServerConnector serverConnector = new ServerConnector(server, connectionFactories);serverConnector.setPort(port);server.setConnectors(new Connector[]{serverConnector});}});return factory;}
}

把配置文件中的server.http2.enable=true开关注释掉,并重启服务。可见h2协议也开启了。

https://i-blog.csdnimg.cn/direct/4b335568738341a7ab1f5380d89692b0.png" width="985" />

3.3 集成Undertow

(1)配置pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>webserver3</artifactId><version>1.0-SNAPSHOT</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.5.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><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>
</project>

(2)配置application.yml

server:port: 8443servlet:context-path: /server3ssl:key-store: classpath:keystore.jkskey-store-password: pass1234key-store-type: JKSkey-alias: wiselykey-password: pass1234http2:enabled: true

(3)启动服务

服务启动后,在浏览器输入:https://127.0.0.1:8443/server3/test/hello

可以看到hello请求协议类型是h2,即HTTP/2。

https://i-blog.csdnimg.cn/direct/4fe93fa4339d4f12af544ca94c43651d.png" width="1155" />

    把配置文件中的server.http2.enable=true开关注释掉,并重启服务,请求接口看到协议类型是http/1.1

    https://i-blog.csdnimg.cn/direct/6b3b0c3819214790bc1316cd5d610843.png" width="1178" />


    http://www.ppmy.cn/embedded/168795.html

    相关文章

    Python解决“比赛配对”问题

    Python解决“比赛配对”问题 问题描述测试样例解决思路代码 问题描述 小R正在组织一个比赛&#xff0c;比赛中有 n 支队伍参赛。比赛遵循以下独特的赛制&#xff1a; 如果当前队伍数为 偶数&#xff0c;那么每支队伍都会与另一支队伍配对。总共进行 n / 2 场比赛&#xff0c;…

    【ISP】畸变校正 LDC

    ISP&#xff08;Image Signal Processor&#xff0c;图像信号处理器&#xff09;中的 LDC&#xff08;Lens Distortion Correction&#xff0c;镜头畸变校正&#xff09;是一种用于校正镜头畸变的图像处理技术。镜头畸变是由于镜头的光学特性导致的图像失真现象&#xff0c;主要…

    用数组实现树的存储遍历【复习笔记】

    1. 树的基本概念 1.1 树的定义和术语 树是由 n&#xff08;n≥0&#xff09;个有限节点组成的一个具有层次关系的集合。当 n0 时&#xff0c;称为空树。在一棵非空树中&#xff0c;有且仅有一个特定的节点称为根节点&#xff1b;其余节点可分为 m 个互不相交的有限集 T1、T2、…

    期权帮|国内期权交易投资人做卖出期权价差交易收取的保证金是单边的还是双向的?

    锦鲤三三每日分享期权知识&#xff0c;帮助期权新手及时有效地掌握即市趋势与新资讯&#xff01; 国内期权交易投资人做卖出期权价差交易收取的保证金是单边的还是双向的? 在国内期权交易中&#xff0c;投资人做卖出期权价差交易时收取的保证金通常是单边的&#xff0c;但具…

    DeepSeek系统架构的逐层分类拆解分析,从底层基础设施到用户端分发全链路

    一、底层基础设施层 1. 硬件服务器集群 算力单元&#xff1a; GPU集群&#xff1a;基于NVIDIA H800/H100 GPU构建&#xff0c;单集群规模超10,000卡&#xff0c;采用NVLink全互联架构实现低延迟通信。国产化支持&#xff1a;适配海光DCU、寒武纪MLU等国产芯片&#xff0c;通过…

    【JAVA-数据结构】Lambda表达式

    还是老规矩&#xff0c;继续进行&#xff0c;有需要的大家持续关注。 1 背景 Lambda表达式是Java SE 8中一个重要的新特性。lambda表达式允许你通过表达式来代替功能接口。 lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达…

    API测试中如何利用Postman和Apipost进行参数编码与加密

    在API测试工作中&#xff0c;开发者和测试人员经常需要对请求中的某些参数进行编码或加密&#xff0c;以满足安全性和系统需求。这些操作可以针对单独的字段&#xff0c;也可以涉及整个请求体的复杂计算。为了解决这些需求&#xff0c;Postman与Apipost这两款流行的API测试工具…

    C++蓝桥杯基础篇(六)

    片头 嗨~小伙伴们&#xff0c;大家好&#xff01;今天我们来一起学习蓝桥杯基础篇&#xff08;六&#xff09;&#xff0c;练习相关的数组习题&#xff0c;准备好了吗&#xff1f;咱们开始咯&#xff01; 第1题 数组的左方区域 这道题&#xff0c;实质上是找规律&#xff0c;…