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

maven

    <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>9</java.version>
</properties>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
<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,移除掉了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改动

    <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>9</java.version>
<servlet-api.version>4.0.0</servlet-api.version>
</properties> <dependencies>
<dependency>
<groupId>io.undertow</groupId>
<artifactId>undertow-core</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>io.undertow</groupId>
<artifactId>undertow-servlet</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>io.undertow</groupId>
<artifactId>undertow-websockets-jsr</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
<exclusions>
<exclusion>
<groupId>io.undertow</groupId>
<artifactId>undertow-core</artifactId>
</exclusion>
<exclusion>
<groupId>io.undertow</groupId>
<artifactId>undertow-servlet</artifactId>
</exclusion>
<exclusion>
<groupId>io.undertow</groupId>
<artifactId>undertow-websockets-jsr</artifactId>
</exclusion>
</exclusions>
</dependency>

由于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("<html>" +
"<img src='/demo.png'>" +
"</html>");
}
} @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

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

  • 启用server push

可以看到如果是用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

http2及server push的更多相关文章

  1. http2 技术整理 nginx 搭建 http2 wireshark 抓包分析 server push 服务端推送

    使用 nginx 搭建一个 http2 的站点,准备所需: 1,域名 .com .net 均可(国内域名需要 icp 备案) 2,云主机一个,可以自由的安装配置软件的服务器 3,https 证书 ht ...

  2. HTTP/2之服务器推送(Server Push)最佳实践

    商业转载请联系腾讯WeTest获得授权,非商业转载请注明出处.   WeTest 导读 HTTP/1.X出色地满足互联网的普遍访问需求,但随着互联网的不断发展,其性能越来越成为瓶颈.IETF在2015 ...

  3. 脑残式网络编程入门(四):快速理解HTTP/2的服务器推送(Server Push)

    本文原作者阮一峰,作者博客:ruanyifeng.com. 1.前言 新一代HTTP/2 协议的主要目的是为了提高网页性能(有关HTTP/2的介绍,请见<从HTTP/0.9到HTTP/2:一文读 ...

  4. HTTP/2 服务器推送(Server Push)教程(HTTP/2 协议的主要目的是提高网页性能,配置Nginx和Apache)

    HTTP/2 协议的主要目的是提高网页性能. 头信息(header)原来是直接传输文本,现在是压缩后传输.原来是同一个 TCP 连接里面,上一个回应(response)发送完了,服务器才能发送下一个, ...

  5. HTTP 笔记与总结(9)分块传输、持久链接 与 反向 ajax(comet / server push / 服务器推技术)

    反向 ajax 又叫 comet / server push / 服务器推技术 应用范围:网页聊天服务器,例如新浪微博在线聊天.google mail 网页聊天 原理:一般而言,HTTP 协议的特点是 ...

  6. Asp.net的服务器推技术 (Server Push)

    在以往的和服务器端通信技术中,我们多数使用的是AJAX轮询式访问,也就是在Javascript中控制时间间隔,然后每隔一段时间就访问一次服务器,然后获得数据或通知.但是这种轮询方式的访问有90%是在做 ...

  7. Server push(服务器推送技术)

    一.服务器推送技术Server Push详解:        推送技术Server Push的基础思想是将浏览器主动查询信息改为服务器主动发送信息.服务器发送一批数据,浏览器显示这些数据,同时保证与服 ...

  8. 让互联网更快,Server Push 特性及开启方式详解

    过去 Nginx 并不支持 HTTP/2 的 Server Push 特性,幸运的是 Nginx 1.13.9 已支持该特性,详情介绍请移步 Nginx 官方博客. Server Push 这个特性是 ...

  9. HTTP/2 Server Push 详解(上)

    收录待用,修改转载已取得腾讯云授权 译者:TAT.Johnny 原文:https://www.smashingmagazine.com/2017/04/guide-http2-server-push/ ...

随机推荐

  1. mysql ab主从复制出错及解决过程

    一.mysql主从服务器报错描述:Slave_IO_Running=NO,Slave_SQL_Running=YES,Last_Errno=0 mysql slave stop ; mysql sla ...

  2. 用 字蛛 取出需要的字符应用字体 @font-face

    一.安装font-spider npm install font-spider -g 二.目录结构 font-spider font FZZZHONGHJW.ttf font.html 三.font. ...

  3. [bzoj2453]维护队列_带修改莫队

    维护队列 bzoj-2453 题目大意:给定一个n个数序列,支持查询区间数的种类数,单点修改.不强制在线. 注释:$1\le n,m\le 10^5$. 想法: 带修改莫队裸题. 如果没有修改操作的话 ...

  4. lines-HDU5124(区间处理 +离散化)

    Problem Description John has several lines. The lines are covered on the X axis. Let A is a point wh ...

  5. 【python】glob模块、os模块

    http://www.cnblogs.com/hongten/p/hongten_python_glob.html http://wenku.baidu.com/link?url=AgUq9_yQVj ...

  6. Windows系统下JAVA开发环境搭建

    首先我们需要下载JDK(JAVA Development Kit),JDK是整个java开发的核心,它包含了JAVA的运行环境,JAVA工具和JAVA基础的类库. 下载地址:http://www.or ...

  7. 七夕节 看到很多停止更新的blog 莫名有点淡淡的忧桑

    又是一年七夕.又是一年单身.看到很多停止更新的blog, 仿佛看到了一茬一茬的程序猿 进入it 圈 又离开it圈,就有莫名的忧桑

  8. Vue2.0生命周期和钩子函数的一些理解

    转自:https://segmentfault.com/a/1190000008010666 前言 在使用vue一个多礼拜后,感觉现在还停留在初级阶段,虽然知道怎么和后端做数据交互,但是对于mount ...

  9. C#之快速排序 C#之插入排序 C#之选择排序 C#之冒泡排序

    C#之快速排序   算法描述 1.假定数组首位元素为“枢轴”,设定数列首位(begin)与末位(end)索引: 2.由末位索引对应元素与“枢轴”进行比较,如果末位索引对应元素大于“枢轴”元素,对末位索 ...

  10. ios打地鼠游戏源代码

    打地鼠游戏源代码,游戏是一款多关卡基于cocos2d的iPad打地鼠游戏源代码,这也是一款高质量的打地鼠游戏源代码,能够拥有逐步上升的关卡的设置,大家能够在关卡时设置一些商业化的模式来盈利的,很完美的 ...