×

Spring Boot:使用Undertow代替Tomcat同时支持HTTP、HTTPS、HTTP/2

96
ImWiki
2018.06.04 01:27* 字数 499

现在越来越多的公司开始支持HTTP/2,相比HTTP有更好的性能。Undertow是一个性能可以和tomcat媲美的容器,Spring Boot也内置了这个容器,本文介绍使用Undertow代替Tomcat,用来实现同时支持HTTP、HTTPS、HTTP/2。

去掉Tomcat依赖,引入Undertow
compile("org.springframework.boot:spring-boot-starter-web"){
    exclude module: 'spring-boot-starter-tomcat', group: 'org.springframework.boot'
}
compile("org.springframework.boot:spring-boot-starter-undertow")
配置支持HTTPS

关于证书问题,这里不展开,免费申请SSL证书:https://freessl.org
修改resources/application.properties,增加证书的配置

server.port=8443
server.ssl.key-store=../xxx.pfx
server.ssl.key-store-password=xxx
server.ssl.keyStoreType=PKCS12
配置支持HTTP/2

由于Spring Boot 2.0已经增加了对HTTP/2的支持,所以启用HTTP/2非常简单,只需要在resources/application.properties开启http2即可。

server.http2.enabled=true
增加HTTP监听

由于我们上面默认启动了HTTPS,所以我们需要增加一个监听,对HTTP的支持

@Configuration
open class SSLConfiguration {
    @Bean
    open fun undertowFactory(): ServletWebServerFactory {
        val undertowFactory = UndertowServletWebServerFactory()
        undertowFactory.addBuilderCustomizers(UndertowBuilderCustomizer {builder ->
            builder.addHttpListener(8080,"0.0.0.0")
        })
        return undertowFactory
    }
}

测试

HTTP测试

上面定义的HTTP端口是8080,所以输入网址http://localhost:8080

HTTPS测试

上面定义的HTTPS端口是8443,所以输入网址https://localhost:8443

查看网站是否支持HTTP/2

打开chrome浏览器,浏览https://localhost:8443网址,然后打开下面的网址,就可以看到已经支持了HTTP/2。

chrome://net-internals/#http2

image.png

神操作!!!

上面的配置中server.ssl.key-store需要写绝对地址,如果我们的签名文件放在resources目录,当打包成Jar格式文件,就无法读取了。解决思路:通过在启动的时候读取resources目录下的签名文件,然后写入当前Jar运行的路径来实现。

  1. 把签名文件放在resources目录。
  2. 修改resources/application.properties,直接填写签名文件名称
server.ssl.key-store=xxxxx.pfx
  1. 启动的时候读取resources下的签名文件,写入当前运行路径,可以放在很多地方,我是放在上面HTTP配置里面。
@Configuration
open class SSLConfiguration {
    @Value("\${server.ssl.key-store:}")
    private val serverSSLKeyStore: String? = null

    @Bean
    open fun undertowFactory(): ServletWebServerFactory {
        // 由于server.ssl.key-store要使用绝对地址,如果我们打包成Jar,这个地址就失效了,所以通过下面方式来实现
        val stream = javaClass.classLoader.getResourceAsStream(serverSSLKeyStore)
        // 然后写入当前应用运行的路径
        val file = File(serverSSLKeyStore)
        file.writeBytes(stream.readBytes())

        val undertowFactory = UndertowServletWebServerFactory()
        undertowFactory.addBuilderCustomizers(UndertowBuilderCustomizer { builder ->
            builder.addHttpListener(8080, "0.0.0.0")
        })
        return undertowFactory
    }
}

神操作完成!!!

微服务与Spring Cloud
Web note ad 1