Java 9 HTTP2的支持功能前瞻

发表于:2017-07-07 09:57:10 来源:  FreeBuf.COM 阅读数(0人)



Java 9预期将于本月27日发布,本文由László Csontos发布在Springuni,讨论了Java 9与HTTP/2有关的特性。


在HTTP/1.1发布后16年,国际互联网工程任务组(IETF)的流媒体工作组在2015年批准了HTTP/2协议。HTTP/2承诺降低网络延迟,并弃用很多在HTTP/1.1中所必需的工作流程,以满足当今的响应时间要求。本文将简要介绍HTTP/2,并谈谈它是怎样使基于文本的HTTP/1.1变得焕然一新的,以及即将来到的Java 9中对HTTP/2的支持功能。


HTTP/1.1早已变得老旧不堪,而1999年以来的互联网已经发生了很多变化。


在互联网上,人们正变得越来越没有耐心,但他们不会注意到,如果响应时间低于100毫秒,那么他们在网络上表现出的行为并不直接由他们自己实施。


当响应时间达到1秒时,就会引起人们的注意了,而当一个网站的响应时间超过10秒时,那么它就会被认为发生了故障。根据一些调查的结果,人们注意力的平均持续时间已经下降到7-8秒,所以即使是1秒的延迟也会造成高达7%的收入损失。


针对HTTP/1.1的网络延迟优化技术


对于HTTP/1.1来说,需要做一些(有时候是很繁重的)工作来满足当今的要求。


由于每个HTTP连接每次只能下载一个资源,所以浏览器为了能够更快地显示页面,就要同时取回这些资源。但是,每个域的并发连接的数量是有限的,而域分片技术(domain sharding)的存在就是用来实现这一目的。

一项类似的优化技术是将多个资源(CSS、JavaScript)捆绑在一起,这样就能够通过一次单独的请求获取到这些资源。这样做好坏参半,在节省了一次网络往返过程的同时,可能会使捆绑资源中的一部分无法使用。在某些情况下,复杂的服务器端逻辑负责选择适当的静态资源,并将它们合并以响应特殊的页面请求。

Image sprites图像精灵是一项与CSS和JavaScript文件捆绑类似的技术,可以减少请求的数量。

还有另一项技术被用于将静态资源内嵌到HTML中。

HTTP/2概述


HTTP/2意在减轻为维护HTTP/1.1复杂的底层架构而带来的痛苦,以提高HTTP/1.1的性能。尽管HTTP/2仍然对HTTP/1.1向下兼容,但它已不再是一个基于文本的协议。当客户端通过HTTP/1.1请求建立一个连接时,所有请求将会被升级。从这一点上看,HTTP/2是用“二进制数据帧”来说话的。


HTTP/2多路复用


HTTP/2多路复用使得一个单独连接可以处理多个双向流,因而客户端可以通过一个单独连接同时下载多个不同的资源。


HTTP/2头部压缩


HTTP 1.x协议族都是基于文本的,因此它们都相当冗长。有时候同一个HTTP头的集合被一遍又一遍地进行交换。HTTP/2在整个请求过程中保持HTTP头 表不变,因而大大降低了所需的带宽。重要的是,这只是在去耦合,而不是经典意义上的压缩。


HTTP/2推送


你可能会认为,HTTP/2推送是某种WebSocket的延续或升级,但实际上并不是这样。WebSocket是客户端和服务器之间全双工通信的一种方法,一旦TCP连接被建立起来,服务器就可以向客户端发送数据,而HTTP/2则解决的是与此不同的问题。


HTTP/2推送一种主动向客户端发送资源的技术,不必由客户端发出请求。这实际上意味着,服务器端知道,一个网站需要一些图片,服务器会在客户端发出请求前的很长时间内,就一次性将这些图片发送到客户端。


Java HTTP客户端支持HTTP/2


根据维基百科关于HTTP/2的一个页面的说法,在编写的时候,以下Java客户端库已能够建立HTTP/2连接。


Jetty

Netty

OkHttp

Vert.x

Firefly

但在这篇文章中,我们关注的是Java 9提供的HTTP/2支持。JEP 110 指定了具体要求,同时声明该项目仍处于孵化状态,这实际上意味着,它将不会取代Java 9中现有的UrlConnection API。 只有在Java 10发布后,标准Java HTTP/2客户端才会被移动到java.net包之下。但同时,它会处于jdk.incubtor命名空间下。


JEP 110为新的、内置的HTTP/2客户端提出了具体要求,因此它提供了一个高级别的、简便易用的API和与现有选项相似(或更高)的性能。


第一步是导入模块jdk.incubator.httpclient。


对于这个例子来说,我们要使用Undertow做为兼容HTTP/2的web服务器。它用来回应客户端发送的消息。


新的API处处遵循生成器模式,而作为初始化HTTP请求入口的HttpClient也不例外。


以阻塞模式发送请求


一旦我们有了一个HttpClient实例,就可以通过一个生成器建立更多的HttpClient实例。


请求被处理多久,send方法就会阻塞多久,但还是有一种方法来异步交换HTTP消息:以非阻塞模式发送请求。


以非阻塞模式发送请求


在下面的例子中,10个随机整数被异步发送到我们的HTTP回显服务器,而当所有请求被初始化后,主线程等待它们完成。


处理push-promise架构


以上全部例子都可以是过时的HTTP/1.1请求。除了创建HttpClient以外,没有看到任何HTTP/2所特有的东西。


这个客户端API中与HTTP/2最有关联的功能很可能是当HTTP/2推送被使用时它处理多个响应的方式。


结论


HTTP/2进行了一些必要改进,使旧的基于文本的协议变得焕然一新,并抛弃了令人讨厌的HTTP/1.1中的很多工作流程,但是它并未解决所有已知的问题。


从Java 9方面来看,新的HTTP/2客户端貌似不错,但它的下一个版本才会是合格的产品。同时,如果需要HTTP/2支持的话,上面的库都可以使用。


相关新闻

大家都在学

课程详情

信息安全基础

课程详情

网络安全漫谈

课程详情

网络安全基础