Spring Boot 2.0中嵌入式Web容器(如Tomcat)对HTTP2的支持详解

Spring Boot应用往往作为服务发布,这里对HTTP2的支持,主要是对通过嵌入式Web容器支持HTTP2。

1. 在最新的Spring Boot 2.0.3中,集成的三种嵌入式Web容器及其版本如下:

  • Tomcat 9.0.10  (Servlet 4.0)
  • Undertow 2.0.9(Servlet 4.0)
  • Jetty 9.4.8  (Servlet 3.1)

从上述Web容器实现的Servlet版本可知,Spring Boot 2.0.3中的Tomcat和Undertow都默认支持HTTP2,而Jetty则不支持HTTP2。


2. 为了便于使用上述Web容器,在Spring Boot的spring-boot-starters项目中,提供了如下的starter模块:

  • spring-boot-starter-tomcat
  • spring-boot-starter-undertow
  • spring-boot-starter-jetty

开发Spring Boot应用时,如果要使用嵌入式Web容器,直接将对应的starter模块加入到Maven项目的pom.xml中即可。


3. 在Spring Boot的spring-boot-samples项目中,给出了分别使用上述三种嵌入式Web容器的示例:

扫描二维码关注公众号,回复: 2102633 查看本文章
  • spring-boot-sample-tomcat
  • spring-boot-sample-undertow
  • spring-boot-sample-jetty

这些示例,可以直接作为对应Spring Boot应用的原型使用。当然,需要将pom.xml中配置的<parent>,从spring-boot-samples改为spring-boot-starter-parent,示例如下:

<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>2.0.3.RELEASE</version>
	<relativePath/> <!-- lookup parent from repository -->
</parent>

这样配置的Web容器只支持HTTP请求响应,要支持HTTPS(这是事实上HTTP2的前提条件之一),还需要为嵌入式Web容器配置SSL。

为了压缩HTTP响应的大小,可以配置application.properties文件的如下属性:

server.compression.enabled=true


4. 在Spring Boot的spring-boot-samples项目中,给出了分别使用上述三种嵌入式Web容器支持HTTPS的示例:

  • spring-boot-sample-tomcat-ssl
  • spring-boot-sample-undertow-ssl
  • spring-boot-sample-jetty-ssl

下面以Tomcat容器为例,分析如下:

1) Maven项目pom.xml
直接依赖spring-boot-starter,并添加对spring-boot-starter-tomcat的依赖;或者依赖spring-boot-starter-web也可以。

添加对Apache HttpComponents httpclient的依赖(仅用于测试)。

2) Spring Boot应用配置application.properties

server.port = 8443
server.ssl.key-store = classpath:my_certs.jks
server.ssl.key-store-password = my_password_for_keystore
server.ssl.key-password = my_password_for_my_key

此外,还有如下两个配置参数,采用默认值即可:

server.ssl.enabled=true#默认为true,无需设置
server.ssl.protocol=TLS#默认为TLS,无需设置

3) 将CA证书my_certs.jks置于Spring Boot应用的classpath中

关于CA证书的生成与签发,我们将在后续文章中详细介绍。


5. 同时支持HTTP/HTTPS的Web容器

Spring Boot应用一旦配置了使用HTTPS,则默认不再支持HTTP。为了使Spring Boot应用同时支持HTTP/HTTPS,需要为该Web容器配置两个connectors。下面以Tomcat为例,在默认配置SSL以支持HTTPS之后,通过一个Spring Bean,定义了一个支持HTTP的Connector,并将该Connector的端口设置为与HTTPS相同:

@SpringBootApplication
public class SampleTomcatTwoConnectorsApplication {
	@Bean
	public ServletWebServerFactory servletContainer() {
		TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
		Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
		connector.setPort(0);
		tomcat.addAdditionalTomcatConnectors(connector);
		return tomcat;
	}

	public static void main(String[] args) {
		SpringApplication.run(SampleTomcatTwoConnectorsApplication.class, args);
	}
}

6. 支持HTTP2的Web容器

Spring Boot 2.0.3最低使用Java 8,但是Java 8默认不能完整支持HTTP2,所以各个Web容器的配置各不相同。

1) 但不管采用哪种Web容器,Spring Boot应用要支持HTTP2,首先必须配置application.properties如下:

server.http2.enabled=true

2) Spring Boot只支持HTTP2的密文传输部分(采用HTTPS),不支持HTTP2的明文传输部分(h2c, HTTP/2 cleartext version),所以Spring Boot应用必须先支持HTTPS,即必须配置Web容器支持SSL,具体过程参考文本第4节。

3) 配置Web容器

对于Undertow 1.4.0+,如果使用Java 8,则无需任何额外配置即可支持HTTP2。

对于Jetty 9.4.8,如果使用Java 8,则还需要conscrypt类库,并需要依赖Jetty的如下两个模块:

  • org.eclipse.jetty:jetty-alpn-conscrypt-server
  • org.eclipse.jetty.http2:http2-server
对于Tomcat 9.0.x,如果使用Java 8,则还需要libtcnative类库,并在启动Tomcat时加入JVM的启动参数如下:

-Djava.library.path=/usr/local/opt/tomcat-native/lib

对于Tomcat 9.0.x,如果使用Java 9,则无需任何额外配置即可支持HTTP2。


参考链接:

https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/

https://github.com/spring-projects/spring-boot/tree/master/spring-boot-project/spring-boot-starters/spring-boot-starter-undertow
https://github.com/spring-projects/spring-boot/tree/master/spring-boot-project/spring-boot-starters/spring-boot-starter-jetty

https://github.com/spring-projects/spring-boot/tree/master/spring-boot-project/spring-boot-starters/spring-boot-starter-tomcat

https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-undertow

https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-jetty

https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-tomcat

https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-undertow-ssl

https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-jetty-ssl

https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-tomcat-ssl

https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-tomcat-multi-connectors


猜你喜欢

转载自blog.csdn.net/taiyangdao/article/details/80977910