java server pushing_java9+springboot2+undertow2启用http2及server push

本文主要研究下java9+springboot2+undertow2启用http2及server push

maven

org.springframework.boot

spring-boot-starter-parent

2.0.0.RELEASE

UTF-8

UTF-8

9

org.springframework.boot

spring-boot-starter-undertow

org.springframework.boot

spring-boot-starter-web

org.springframework.boot

spring-boot-starter-tomcat

复制代码注意这里使用undertow,移除掉了starter-web中的tomcat依赖

配置

application.yml

server:

port: 8443

ssl:

key-store: classpath:keystore.jks

key-store-password: xxx

key-password: xxx

protocol: TLSv1.2

http2:

enabled: true

use-forward-headers: true

复制代码keystore生成实例

keytool -genkey -keyalg RSA -alias selfsigned -keystore src/main/resources/keystore.jks -storepass xxx -validity 360 -keysize 2048

复制代码

ENABLE_HTTP2及ENABLE_PUSH

@Configuration

public class Http2Config {

@Bean

UndertowServletWebServerFactory undertowServletWebServerFactory() {

UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory();

factory.addBuilderCustomizers(

builder -> {

builder.setServerOption(UndertowOptions.ENABLE_HTTP2, true)

.setServerOption(UndertowOptions.HTTP2_SETTINGS_ENABLE_PUSH,true);

});

return factory;

}

}

复制代码这里开启了HTTP2以及server push功能

HTTP2实例

controller

@RestController

public class IndexController {

/**

* curl -Ik --http2 https://localhost:8443/hello

* @return

*/

@GetMapping("/hello")

public String hello(){

return "hello";

}

}

复制代码

运行

curl -Ivk --http2 https://localhost:8443/hello

* Trying ::1...

* Connected to localhost (::1) port 8443 (#0)

* ALPN, offering h2

* ALPN, offering http/1.1

* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH

* successfully set certificate verify locations:

* CAfile: /usr/local/etc/openssl/cert.pem

CApath: none

* TLSv1.2 (OUT), TLS header, Certificate Status (22):

* TLSv1.2 (OUT), TLS handshake, Client hello (1):

* TLSv1.2 (IN), TLS handshake, Server hello (2):

* TLSv1.2 (IN), TLS handshake, Certificate (11):

* TLSv1.2 (IN), TLS handshake, Server key exchange (12):

* TLSv1.2 (IN), TLS handshake, Server finished (14):

* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):

* TLSv1.2 (OUT), TLS change cipher, Client hello (1):

* TLSv1.2 (OUT), TLS handshake, Finished (20):

* TLSv1.2 (IN), TLS change cipher, Client hello (1):

* TLSv1.2 (IN), TLS handshake, Finished (20):

* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384

* ALPN, server accepted to use h2

* Server certificate:

* subject: C=ZH; ST=guangdong; L=shenzhen; O=spring; OU=springboot; CN=localhost

* start date: Mar 9 14:10:54 2018 GMT

* expire date: Mar 4 14:10:54 2019 GMT

* issuer: C=ZH; ST=guangdong; L=shenzhen; O=spring; OU=springboot; CN=localhost

* SSL certificate verify result: self signed certificate (18), continuing anyway.

* Using HTTP2, server supports multi-use

* Connection state changed (HTTP/2 confirmed)

* TCP_NODELAY set

* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0

* Using Stream ID: 1 (easy handle 0x7f8a5280ea00)

> HEAD /hello HTTP/1.1

> Host: localhost:8443

> User-Agent: curl/7.46.0

> Accept: */*

>

< HTTP/2.0 200

HTTP/2.0 200

< content-type:text/plain;charset=UTF-8

content-type:text/plain;charset=UTF-8

< content-length:5

content-length:5

< date:Fri, 09 Mar 2018 15:18:36 GMT

date:Fri, 09 Mar 2018 15:18:36 GMT

<

* Connection #0 to host localhost left intact

复制代码注意,这里curl命令使用-k参数忽略校验https,否则报错

curl -I --http2 https://localhost:8443/hello

curl: (60) SSL certificate problem: self signed certificate

More details here: http://curl.haxx.se/docs/sslcerts.html

curl performs SSL certificate verification by default, using a "bundle"

of Certificate Authority (CA) public keys (CA certs). If the default

bundle file isn't adequate, you can specify an alternate file

using the --cacert option.

If this HTTPS server uses a certificate signed by a CA represented in

the bundle, the certificate verification probably failed due to a

problem with the certificate (it might be expired, or the name might

not match the domain name in the URL).

If you'd like to turn off curl's verification of the certificate, use

the -k (or --insecure) option.复制代码

server push实例

maven改动

UTF-8

UTF-8

9

4.0.0

io.undertow

undertow-core

2.0.1.Final

io.undertow

undertow-servlet

2.0.1.Final

io.undertow

undertow-websockets-jsr

2.0.1.Final

org.springframework.boot

spring-boot-starter-undertow

io.undertow

undertow-core

io.undertow

undertow-servlet

io.undertow

undertow-websockets-jsr

复制代码由于server push需要servlet4版本,目前springboot2依赖的undertow还是1.4版本的还只是servlet3,因此这里需要额外exclude掉再引入undertow2版本以支持servelt4

controller

@GetMapping("/demo")

public void http2ServerPush(HttpServletRequest request, HttpServletResponse response) throws IOException {

PushBuilder pushBuilder = request.newPushBuilder();

pushBuilder

.path("/demo.png")

.addHeader("content-type", "image/png")

.push();

try(PrintWriter respWriter = response.getWriter()){

respWriter.write("" +

"demo.png" +

"");

}

}

@GetMapping(value = "/demo.png")

public void download(HttpServletResponse response) throws IOException {

InputStream data = getClass().getClassLoader().getResourceAsStream("demo.png");

response.setHeader("content-type", "image/png");

FileCopyUtils.copy(data,response.getOutputStream());

}

复制代码

运行

不启用server push

82e091bd13df59c584f36f9a3e7161c0.png

没有用server push,在在Initiator那栏,看到的是/demo这个触发的。点开waterfall,会看到Content Download的耗时。

启用server push

82d74f8d97830b25a53ef0866fe97b09.png

可以看到如果是用server push的,在Initiator那栏,有个Push标识,点开waterfall,会看到reading push的耗时。

小结

随着java9支持HTTP2,servlet4引入PushBuilder支持server push,使用java作为服务端开发语言的开发者可以更方便地将HTTP2实践起来。

截止到写这篇文章之时,几大servlet容器的servlet4支持情况:

jetty尚且没有看到支持servlet4的实现版本发布;

tomcat有9.x版本支持servlet4,但是在springboot2上替换依赖报错,整体实践起来稍稍麻烦;

undertow2.0.1.Final版本支持servlet4,在springboot2上替换依赖,非常简单,没有报错,这也是本文选择undertow的原因。

doc

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值