Spring Boot应用往往作为服务发布,这里对HTTP2的支持,主要是对通过嵌入式Web容器支持HTTP2。
1. 在最新的Spring Boot 2.0.3.RELEASE中,集成的三种嵌入式Web容器及其版本如下:
从上述Web容器实现的Servlet版本可知,Spring Boot 2.0.3中的Jetty,Tomcat和Undertow尚不支持HTTP2。可以在开发过程中升级Web容器,但是Tomcat难以实现,最容易的是Undertow。
2. 为了便于使用上述Web容器,在Spring Boot的spring-boot-starters项目中,提供了如下的starter模块:
开发Spring Boot应用时,如果要使用嵌入式Web容器,直接将对应的starter模块加入到Maven项目的pom.xml中即可。
3. 在Spring Boot的spring-boot-samples项目中,给出了分别使用上述三种嵌入式Web容器的示例:
这些示例,可以直接作为对应Spring Boot应用的原型使用。当然,需要将pom.xml中配置的
org.springframework.boot
spring-boot-starter-parent
2.0.3.RELEASE
这样配置的Web容器只支持HTTP请求响应,要支持HTTPS(这是事实上HTTP2的前提条件之一),还需要为嵌入式Web容器配置SSL。
为了压缩HTTP响应的大小,可以配置application.properties文件的如下属性:
server.compression.enabled=true
4. 在Spring Boot的spring-boot-samples项目中,给出了分别使用上述三种嵌入式Web容器支持HTTPS的示例:
下面以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.11,如果使用Java 8,则还需要conscrypt类库,并需要依赖Jetty的如下两个模块:
对于Tomcat 9.0.x,如果使用Java 8,则还需要单独下载libtcnative类库(使用其中的APR连接器,并设置升级协议为Http2Protocol),并在启动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