目录
一、常用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、特性
- 多路复用:HTTP/2允许同时发送多个请求和响应,而不是像HTTP/1.1一样只能一个一个地处理。如允许以减少延迟,提高效率,提高网络吞吐量。
- 二进制传输:HTTP/2利用二进制协议,与HTTP/1.1利用的文本协议差别。二进制协议可以更快地解析,更有用地传输数据,减少了传输过程中的开销和延迟。
- 头部压缩:HTTP/2利用HPACK算法对HTTP头部进行压缩,减少了头部传输的数据量,从而减少了网络延迟。
- 服务器推送:HTTP/2支持服务器推送,允许服务器在客户端请求之前推送资源,以提高性能。
- 改进的安全性:HTTP/2默认利用TLS(Transport Layer Security)加密传输数据,提高了安全性。
- 兼容HTTP/1.1:HTTP/2可以与HTTP/1.1共存,服务器可以同时支持HTTP/1.1和HTTP/2。如果客户端不支持HTTP/2,服务器可以回退到HTTP/1.1。
3、优点
- 解析效率高:二进制数据更易于机器处理,提高了解析效率。
- 紧凑性好:减少了冗余字符和格式化问题,使得数据更加紧凑。
- 低错误率:避免了HTTP/1.1中容易因空格、大小写、换行符等问题导致的错误。
- 减少请求次数:服务器推送功能允许服务器在响应客户端请求时,提前发送额外的资源,减少了客户端的请求次数和等候时间。
4、与HTTP/1.1的区别
- 连接管理:HTTP/1.1中,每个请求都需要单独建立和维护连接;而HTTP/2允许同时在同一连接中发送多个请求和响应。
- 头部传输:HTTP/1.1中,头部字段需要在每个请求和响应中重复发送;而HTTP/2对头部进行了压缩,减少了重复的数据传输。
- 服务器推送:HTTP/1.1中,服务器无法自动推送额外的资源给客户端;而HTTP/2使服务器能够自动推送额外的资源给客户端。
- 安全性: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: 8443
- servlet:
- context-path: /server1
- ssl:
- key-store: classpath:keystore.jks
- key-store-password: pass1234
- key-store-type: JKS
- key-alias: wisely
- key-password: pass1234
- http2:
- enabled: true
复制代码 (3)启动服务
服务启动后,在浏览器输入:https://127.0.0.1:8443/server1/test/hello
可以看到hello请求协议类型是h2,即HTTP/2。
如果利用Google浏览器,Network默认不表现Protocol,在表头这一行右键,选择需要表现的列。
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: 8443
- servlet:
- context-path: /server2
- ssl:
- key-store: classpath:keystore.jks
- key-store-password: pass1234
- key-store-type: JKS
- key-alias: wisely
- key-password: pass1234
- http2:
- enabled: true
- jetty:
- threads:
- acceptors: 4
- selectors: 8
复制代码 (3)启动服务
服务启动后,查看日志输出,打印出(ssl, alpn, h2, http/1.1),则表现h2启用成功。

在浏览器输入:https://127.0.0.1:8443/server2/test/hello
可以看到hello请求协议类型是h2,即HTTP/2。

(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
- @Autowired
- public 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协议也开启了。

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: 8443
- servlet:
- context-path: /server3
- ssl:
- key-store: classpath:keystore.jks
- key-store-password: pass1234
- key-store-type: JKS
- key-alias: wisely
- key-password: pass1234
- http2:
- enabled: true
复制代码 (3)启动服务
服务启动后,在浏览器输入:https://127.0.0.1:8443/server3/test/hello
可以看到hello请求协议类型是h2,即HTTP/2。
把设置文件中的server.http2.enable=true开关注释掉,并重启服务,请求接口看到协议类型是http/1.1
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |