http2

HTTP2.0大幅度的提高了web性能,在HTTP1.1完全语意兼容的基础上,进一步减少了网络的延迟。实现低延迟高吞吐量。对于前端开发者而言,减少了优化工作。
二进制分帧
首部压缩
流量控制
多路复用
请求优先级
服务器推送

二进制分帧
在不改变HTTP1.x的语义、方法、状态码。URL以及首部字段的情况下,HTTP2.0是怎样突破HTTP1.1的性能限制,改进传输性能,实现低延迟高吞吐量的呢?关键之一就是在应用层(HTTP)和传输层(TCP)之间增加一个二进制分帧层。
在整理二进制分帧及其作用的时候我们先来铺垫一点关于帧的知识:



帧:HTTP2.0通信的最小单位,所有帧都共享一个8字节的首部,其中包含帧的长度、类型、标志、还有一个保留位,并且至少有标识出当前帧所属的流的标识符,帧承载着特定类型的数据,如HTTP首部、负荷、等等。
消息:比帧大的通讯单位,是指逻辑上的HTTP消息,比如请求、响应等。由一个或多个帧组成
流:比消息大的通讯单位。是TCP连接中的一个虚拟通道,可以承载双向的消息。每个流都有一个唯一的整数标识符



什么是二进制分帧
在二进制分帧层上,HTTP2.0会将所有传输信息分割为更小的消息和帧,并对它们采用二进制格式的编码将其封装。其中,HTTP1.X中的首部信息header封装到Headers帧中,而request body将被封装到Data帧中。
二进制分帧如何工作
HTTP2.0通信都在一个TCP连接上完成,这个连接可以承载任意数量的双向数据流,相应的每个数据流以消息的形式发送。而消息由一或多个帧组成,这些帧可以乱序发送,然后根据每个帧首部的流标识符重新组装。
二进制分帧对性能优化工作的贡献
二进制分帧主要是为下文中的各种特性提供了基础。它能把一个数据划分封装为更小更便捷的数据。首先是在单链接多资源方式中,减少了服务端的链接压力,内存占用更少,链接吞吐量更大。这一点可以结合下文中的多路复用来体会。另一方面,由于TCP链接的减少而使网络拥塞状态得以改善,同时慢启动时间的减少。使拥塞和丢包恢复的速度更快。
首部压缩
HTTP1.1并不支持HTTP首部压缩,为此SPDY和HTTP2.0出现了。SPDY是用的是DEFLATE算法,而HTTP2.0则使用了专门为首部压缩设计的HPACK算法。
什么是首部压缩
HTTP1.x每次通讯(请求或响应)都会携带首部信息用于描述资源属性。而HTTP2.0在客户端和服务端之间使用首部表来跟踪和存储之前发送的键值对。请求与响应首部的定义在HTTP2.0中基本没有变,只是所有首部键必须全部小写,而且要求行要独立为:method:、:scheme:、:host:、:path:这些键值对
首部压缩如何工作
对于相同的数据,不再重新通过每次请求和响应发送。每个新的首部键值对要么追加到当前表的末尾,要么替换表中之前的值。首部表在HTTP2.0的链接存续期内始终存在,由客户端和服务端共同渐进的更新。



首部压缩性能优化工作的贡献
首部表在HTTP2.0使用了首部压缩的技术。使报头更紧凑,更快速传输,有利于移动网络环境。减少每次通讯的数据量,使网络拥塞状态得以改善。
流量控制
HTTP2.0为数据流和连接的流量提供了一个简单的机制:



流量基于HTTP链接的每一跳进行,而非端到端的控制
流量控制基于窗口更新帧进行,即接收方广播自己准备接收某个数据流的多少字节,以及对整个链接要接收多少个字节。
流量控制有方向性,即接收方可能根据自己的情况为没个流乃至整个链接设置任意窗口大小
流量控制可以由接收方禁用,包括针对个别的流和针对整个链接。
帧的类型决定了流量控制是否适用于帧,目前只有DATA帧服从流量控制,所有其他类型的帧并不会消耗流量控制窗口的空间。这保证了重要的控制帧不会被流量控制阻塞



多路复用
在HTTP1.1中,浏览器客户端在同一时间,针对同一域名下的请求有一定数量的限制。超过限制数目的请求会被阻塞。而HTTP2.0中的多路复用优化了这一性能。
什么是多路复用
基于二进制分帧层,HTTP2.0可以在共享TCP链接的基础上同时发送请求和响应。HTTP消息被分解为独立的帧,而不破坏消息本身的语义,交错发出去,在另一端根据流标识符和首部将他们重新组装起来。
多路复用如何工作
我们来通过与HTTP1.X的对比来看看他是如何工作的。



多路复用对性能优化工作的贡献



可以并行交错的发送请求和响应,这些请求和响应之间互不影响
只使用一个链接即可并行发送多个请求和响应
消除不必要的延迟,从而减少页面加载的时间
不必再为绕过HTTP1.x限制而多做很多工作



请求优先级
把HTTP消息分为很多独立帧之后,就可以通过优化这些帧的交错和传输顺序进一步优化性能。
什么是请求优先级
每个流都可以带有一个31bit的优先值:0表示最高优先级;2的31次方-1表示最低优先级。
请求优先级如何工作
客户端明确指定优先级,服务端可以根据这个优先级作为交互数据的依据,比如客户端优先设置为.css>.js>.jpg。服务端按此顺序返回结果更加有利于高效利用底层连接,提高用户体验。然而,在使用请求优先级时应注意服务端是否支持请求优先级,是否会引起队首阻塞问题,比如高优先级的慢响应请求会阻塞其他资源的交互。
请求优先级对性能优化工作的贡献
服务器可以根据流的优先级控制资源分配(CPU、内存、宽带),而在响应数据准备好之后,优先将最高优先级的帧发送给客户端。浏览器可以在发现资源时立即分派请求,指定每个流的优先级,让服务器决定最优的响应次序。这样请求就不用排队了,既节省了时间,又最大限度的利用了每个连接。
服务器推送
HTTP2.0新增的一个强大的新功能,就是服务器可以对一个客户端请求发送多个响应。服务器向客户端推送资源无需客户端明确的请求。
什么是服务器推送(HTTP2.0中)
服务端根据客户端的请求,提前返回多个响应,推送额外的资源给客户端。如下图,客户端请求stream 1(/page.html)。服务端在返回stream 1的消息的同时推送了stream 2(/script.js)和stream 4(/style.css)



服务器推送如何工作



PUSH_PROMISE帧是服务端向客户端有意推送资源的信号。
PUSH_PROMISE帧中只包含预推送资源的首部。如果客户端对PUSH_PROMISE帧没有意见,服务端在PUSH_PROMISE帧后发送响应的DATA帧。如果客户端已经缓存了该资源,不需要推送,可以拒绝PUSH_PROMISE帧。
PUSH-PROMISE必须遵循请求-响应原则,只能借着对请求的响应推送资源。
PUSH_PROMISE帧必须在返回响应之前发送,以免客户端出现竞态条件(竞态条件是指在多线程的情况下不同的执行顺序会导致计算机执行出不同的结果正确性不同)
HTTP2.0连接后,客户端与服务端交换SETTINGS帧,借此限定双向并发的最大数量。因此,客户端可以限定推送流的数量,或者通过把这个只设置为0来完全禁止服务器推送。
所有推送的资源都必须遵守同源策略。换句话说,服务器不能随便将第三方资源推送给客户端,而必须是经过双方的确认才行。



服务器推送对性能优化工作的贡献
服务端推送是一种在客户端请求之前发送数据的机制。在HTTP2.0中,服务器可以对一个客户端的请求发送多个响应。如果一个请求是由你的主页发送的,服务器可能会响应主页内容、logo以及样式表,因为他知道客户端会用到这些东西。这样不但减轻了数据传送冗余步骤,也加快了页面响应的速度,提高了用户体验



HTTP/2 更简单,高效,强大.它在传输层解决了以前我们HTTP1.x中一直存在的问题.使用它可以优化我们的应用.HTTP/2 的首要目标是通过完全的请求,响应多路复用,头部的压缩头部域来减小头部的体积,添加了请求优先级,服务端推送.为了支持这些特性,他需要大量的协议增加头部字段来支持,例如新的流量控制,差错处理,升级机制.而这些是每个web开发者都应该在他们的应用中用到的.
HTTP/2并没有在应用中改变HTTP的语义,而是通过在客户端和服务端传输的数据格式(frame)和传输.它通过在新的二进制帧层控制整个过程以及隐藏复杂性,而这不需要改变原来有的东西就可以实现.




  1. 设计和技术目标
    HTTP是因特网广泛普及和采纳的应用层协议.它的易于实现性同样有了对应用性能方面的影响.HTTP/1.x 需要开启多个连接来实现并发和减少潜在影响.HTTP/1.x 的头部没有压缩,造成不必要的网络拥塞.HTTP/1.x没有应用资源优先级,导致重要Tcp连接的糟糕使用.
    它的好处如下;



HTTP/2 enables a more efficient use of network resources and a reduced perception of latency by introducing header field compression and allowing multiple concurrent exchanges on the same connection… Specifically, it allows interleaving of request and response messages on the same connection and uses an efficient coding for HTTP header fields. It also allows prioritization of requests, letting more important requests complete more quickly, further improving performance.
The resulting protocol is more friendly to the network, because fewer TCP connections can be used in comparison to HTTP/1.x. This means less competition with other flows, and longer-lived connections, which in turn leads to better utilization of available network capacity. Finally, HTTP/2 also enables more efficient processing of messages through use of binary message framing.
HTTP2.0并没有改变之前HTTP的语义,也就是说高层的Api并没有改变,它是在底层通过二进制frame来改变性能的.




  1. 二进制帧层
    性能提升的核心在于二进制帧层.它指HTTP消息在客户端和服务端如何封装和传输.
    这一层指一个设计选择,它在socket接口之间采用一种更好的编码机制,而高层的Api提供给我们的应用。与HTTP1.x的采用的换行符分隔文本不同,HTTP/2 消息被分成很小的消息和frame,然后每个消息和frame用二进制编码。客户端和服务端都采用二进制编码和解码。HTTP/1.x 的客户端不能与只有HTTP/2的服务端通信。幸运的是,我们的应用还没意识到这些改变。客户端和服务端能够很好的处理这些帧。



ASCII 协议能够很容易的看出来和开始使用。然而它们是没有效率的,且很难正确设计:可选的空白,改变终止序列和其他的毛病使得协议很难区别出payload。虽然二进制协议用起来需要做很多工作,但是它们能表现出更好的性能。




  1. 流,消息,帧
    接下来介绍二进制帧机制来明白数据如何在客户端和服务端交换的。



流:已经建立的连接之间双向流动的字节,它能携带一个至多个消息。
消息:一个完整的帧序列,它映射到逻辑的请求和响应消息。
帧:在HTTP/2通信的最小单元。每个桢包括一个帧头,里面有个很小标志,来区别是属于哪个流。



所有的通信都建立在一个TCP连接上,可以传递大量的双向流通的流。
每个流都有独一无二的标志和优先级。
每个消息都是逻辑上的请求和相应消息。由一个或者多个帧组成。
来自不同流的帧可以通过帧头的标志来关联和组装起来。
这是 HTTP/2 协议提供高性能的基础。




  1. 请求和响应的多路复用
    在HTTP/1.x中,用户想要多个并行的请求来提高性能,但是这样必须得使用多个TCP连接.这样的操作是属于HTTP/1.x 发送模型的直接序列.它能保证在每次连接中在一个时间点只有一个响应被发送出去.更糟糕的是,它使得队头阻塞和重要TCP连接的低效使用.
    在HTTP/2中,新的二进制帧层,解除了这个限制.使得所有的请求和响应多路复用.通过允许客户端和服务端把HTTP消息分解成独立的帧,交错传输,然后在另一端组装.



图12-3显示了在一次连接中的多个流.客户端传输数据帧到服务端(Stream5).服务端传输交错的帧序列(Stream1,Stream3)到客户端.此时,同时存在并行的3个流.
能够把HTTP消息分解成交错的帧,并在另一端组装它们是HTTP/2中一个非常重要的提高.事实上,它引起了一种波浪效应使得web技术的全栈在性能上有很大的提升.它有以下作用:



交错的多个并行的请求或者,而不需要阻塞.
使用一个连接传递所有的并行的请求和响应.
移除了HTTP/1.x中没有的必要的解决方法.例如级联文件,域分片.
淘汰没必要的潜在因素来降低页面载入的时间.提升可用网络容积的使用率.
新的二进制帧层解决了HTTP/1.X中头部阻塞的问题.在并行处理和传输的请求和响应不再需要多个连接.这使得我们的应用更简单,快捷和便宜.




  1. 流的优先级.
    为了能方便流的传输顺序,HTTP/2.0提出,使每个流都有一个权重和依赖.



每个流的权重值在1~256之间
每个流可以详细给出对其他流的依赖
流权重和依赖的结合使客户端可以构造和通信一个优先级二叉树来表达它更想得到哪种响应.然后服务端可以按权重分配硬件资源(CPU,内存).



在HTTP/2 ,一个流的依赖可以显式用其他流的标志来表达,如果省略了标志,则说明它的依赖是根流.一般来说,父流应该在它的依赖流之前分配资源,例如D应该是C之前被发送.依赖于同一父节点的应该按照他们的权重分配资源.例如A结点的权重为12,它的兄弟结点B的结点的权重为4.然后按比例分资源,A占12/16,B占4/16.如上面所述,流的依赖和权重提供了一种很好的表达式语言来表达资源的优先级.但是我们应该明白,,流的依赖和权重只是提供了一种传输偏好,而不是说一定是这样的比例.



5.每个源一个连接
HTTP/2.0的连接是持久的,每个源仅仅需要一个连接.大部分HTTP的传输是短的,并且突然的.然而TCP连接却适合长期存活的,批量的数据传输.通过利用相同的HTTP/2 连接,既能够充分利用TCP连接,也能减小整体协议的头部.更进一步来说,更少的连接内存的占用以及全连接路径的处理过程.向HTTP/2的转移不仅减少了网络潜在因素,更减少了操作代价.



Tips:减少连接,同时也提高了HTTPS的性能,因为仅需要更少的TLS层的握手.




  1. 流量控制
    流量控制是一种机制,用来阻止发送者发送大量的接收者不需要,或者没能力处理的数据.接收者可能会在重负下很繁忙,或者只愿意分配固定的资源给特定的流.例如,客户端可能以高的优先级请求大量的视频数据,然后用户暂停了视频,那么客户端现在想要停止或者减少服务端的传输来避免取和缓存没必要的数据.或者一个代理服务器连接有很快的下流,很慢的上流,同样的也要控制以多大的流速传输数据,从而匹配上流的速度,从而控制资源的使用.



这些需求可能让你想起了TCP流量控制,由于HTTP/2的那些流是在一个TCP的连接上.那么TCP连接不够细粒度,也没能提供应用级的API来控制单个流的传输.为了应对这种情况,HTTP/2提供了一系列的简单修筑块,来允许客户端和服务端实现他们自己的流级别的,连接级别的流量控制.



流量控制是有方向的.对于每个流和连接,每个接收者可以设置它想要窗口大小.
流量控制是基于信用的。每个接收者通告其初始连接和流量控制窗口(以字节为单位),只要发送者发送数据帧并通过接受者发送的WINDOW_UPDATE帧递增,该窗口就会减少。
流量控制不能禁用.当建立HTTP / 2连接时,客户端和服务器交换SETTINGS帧,这些帧设置双向流量控制窗口的大小。流量控制窗口的默认值设置为65,535字节,但接收方可以设置更大的最大窗口大小(2的31次方-1
字节),并通过在接收到任何数据时发送WINDOW_UPDATE帧来维护它。
流量控制是逐跳的,而不是端到端的.也就是说,一个中介可以使用它控制资源的使用,从而根据自己的标准和启发式实现资源分配机制.
HTTP / 2没有规定用于实现流量控制的任何特定算法。相反,它提供了简单的构建模块并将实现推迟到客户端和服务器,这可以用它来实现自定义策略来调节资源使用和分配,以及实现新的传输功能,这可能有助于提高Web应用程序真实性和感知性。



例如,应用程序层流控量制允许浏览器仅提取特定资源的一部分,通过将流量控制窗口降至零来暂停提取,然后稍后恢复 - 例如,获取预览或第一次浏览图像,显示图像并允许进行其他高优先级操作取来操作,并在关键资源完成加载后又开始取。



6.服务端推送
HTTP / 2的另一个强大的新功能是服务器为单个客户端请求发送多个响应的能力。也就是说,除了对原始请求的响应之外,服务器还可以向客户端推送额外的资源(图12-5),而不需要客户端明确请求每一个资源!



image.png
HTTP / 2脱离了严格的请求 - 响应语义,并支持一对多和服务器启动的推送工作流程,在浏览器内部和外部打开全新的交互可能性。这是一个启动功能,对于我们如何考虑协议以及在何处以及如何使用协议,都会产生重要的长期影响。



为什么我们需要在浏览器中使用这种机制?一个典型的Web应用程序由几十个资源组成,所有这些资源都是客户端通过检查服务器提供的文档发现的。因此,为什么不消除额外的延迟并让服务器提前推送相关资源?服务器已经知道客户端需要哪些资源;这是服务器推动。
事实上,如果您曾经通过数据URI将CSS,JavaScript或任何其他资产内联到一起(请参阅资源内联),那么您已经有了服务器推送的实践经验!通过手动将资源内联到文档中,实际上,我们将该资源推送到客户端,而无需等待客户端请求。通过HTTP / 2,我们可以获得相同的结果,但是具有额外的性能优势:



推送的资源可以由客户端缓存



推送的资源可以在不同的页面上重复使用



推送的资源可以与其他资源一起复用



推送的资源可以由服务器优先



推送的资源可以被客户拒绝



每个推送的资源都是一个流,与内联资源不同,它允许客户端对其进行单独复用,优先化和处理。由浏览器执行的唯一安全限制是推送资源必须遵守同源策略:服务器必须对提供的内容具有权限。




  1. 头部压缩
    每个HTTP传输都包含一组描述传输资源及其属性的标题。在HTTP / 1.x中,此元数据始终以纯文本形式发送,并且每次传输的开销都会在任何位置增加500-800字节,如果使用HTTP Cookie,则会增加数千字节。为了减少这种开销并提高性能,HTTP / 2使用两种简单但强大的技术使用HPACK压缩格式(要了解这个算法,可以参考这篇文章https://imququ.com/post/header-compression-in-http2.html)来压缩请求和响应头元数据:



它允许通过静态霍夫曼编码对传输的头部字段进行编码,从而减少它们各自的传输大小。



它要求客户端和服务器都维护和更新先前看到的标题字段的索引列表(即,建立共享压缩上下文),然后将其用作参考以高效编码先前传输的值。



霍夫曼编码允许单个值在传输时被压缩,并且先前传输值的索引列表允许我们通过传输索引值来编码重复值(图12-6),索引值可用于有效地查找和重建完整头部键和值。



image.png



作为进一步优化,HPACK压缩上下文由静态和动态表组成:静态表在规范中定义,并提供所有连接可能使用的常见HTTP头字段的列表(例如,有效头名称);动态表最初是空的,并基于特定连接内的交换值进行更新。因此,通过对以前未见过的值使用静态霍夫曼编码,并将索引替换为已存在于客户端和服务端静态或动态表中的值的索引,可以减少每个请求的大小。




  1. 二进制帧的简短介绍
    所有HTTP / 2改进的核心是新的二进制长度前缀成帧层。与以换行符分隔的纯文本HTTP / 1.x协议相比,二进制框架提供了更紧凑的表示形式,可以更高效地处理并更容易正确实现。
    一旦建立了HTTP / 2连接,客户端和服务器就通过交换帧来进行通信,这些帧用作协议内最小的通信单元。所有帧共享一个共同的9字节头(图12-7),其中包含帧的长度,类型,标志位字段和31位流标识符。



image.png
24位长度字段允许一个帧携带2的24次方数据字节。



8位类型字段确定帧的格式和语义。



8位标志字段传递帧类型特定的布尔标志。



1位保留字段始终设置为0。



31位流标识符唯一标识HTTP / 2流。



从技术上讲,长度字段允许每帧高达字节(〜16MB)的有效载荷。但是,HTTP / 2标准将DATA帧的默认最大有效负载大小设置为每帧字节(〜16KB),并允许客户端和服务器协商较高的值。更大并不总是更好:较小的帧大小能够实现高效的多路复用并将头部阻塞降至最低。




  1. 分析二进制帧数据流
    掌握了不同帧类型的知识后,我们现在可以重新看下我们前面在请求和响应复用中遇到的图(图12-10)并分析HTTP / 2交换:



image.png
有三个流,ID设置为1,3和5。



所有三个流ID都是奇数;所有这三个都是客户端启动的流。(即发起方是客户端)



在这个交换中没有服务器启动(“推送”)流。(即服务端推送)



服务器正在为流1发送交错数据帧,这些数据帧携带应用程序响应客户端先前的请求。



服务器已经在数据帧之间为流3交错了HEADERS和DATA帧,以便实现流1响应多路复用!



客户端正在传输数据流5的数据帧,这表明HEADERS帧已在先传输。



当然,上述分析基于实际HTTP / 2交换的简化表示,但它仍然说明了新协议的许多优点和特点.



二、HTTP的基本优化



影响一个 HTTP 网络请求的因素主要有两个:带宽和延迟。



带宽:如果说我们还停留在拨号上网的阶段,带宽可能会成为一个比较严重影响请求的问题,但是现在网络基础建设已经使得带宽得到极大的提升,我们不再会担心由带宽而影响网速,那么就只剩下延迟了。



延迟:



浏览器阻塞(HOL blocking):浏览器会因为一些原因阻塞请求。浏览器对于同一个域名,同时只能有 4 个连接(这个根据浏览器内核不同可能会有所差异),超过浏览器最大连接数限制,后续请求就会被阻塞。



DNS 查询(DNS Lookup):浏览器需要知道目标服务器的 IP 才能建立连接。将域名解析为 IP 的这个系统就是 DNS。这个通常可以利用DNS缓存结果来达到减少这个时间的目的。



建立连接(Initial connection):HTTP 是基于 TCP 协议的,浏览器最快也要在第三次握手时才能捎带 HTTP 请求报文,达到真正的建立连接,但是这些连接无法复用会导致每次请求都经历三次握手和慢启动。三次握手在高延迟的场景下影响较明显,慢启动则对文件类大请求影响较大。



三、HTTP1.0和HTTP1.1的一些区别



HTTP1.0最早在网页中使用是在1996年,那个时候只是使用一些较为简单的网页上和网络请求上,而HTTP1.1则在1999年才开始广泛应用于现在的各大浏览器网络请求中,同时HTTP1.1也是当前使用最为广泛的HTTP协议。 主要区别主要体现在:



缓存处理,在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。



带宽优化及网络连接的使用,HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1则在请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。



错误通知的管理,在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。



Host头处理,在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误(400 Bad Request)。



长连接,HTTP 1.1支持长连接(PersistentConnection)和请求的流水线(Pipelining)处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启Connection: keep-alive,一定程度上弥补了HTTP1.0每次请求都要创建连接的缺点。



四、HTTPS与HTTP的一些区别



HTTPS协议需要到CA申请证书,一般免费证书很少,需要交费。



HTTP协议运行在TCP之上,所有传输的内容都是明文,HTTPS运行在SSL/TLS之上,SSL/TLS运行在TCP之上,所有传输的内容都经过加密的。



HTTP和HTTPS使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。



HTTPS可以有效的防止运营商劫持,解决了防劫持的一个大问题。



五、SPDY:HTTP1.x的优化



2012年google如一声惊雷提出了SPDY的方案,优化了HTTP1.X的请求延迟,解决了HTTP1.X的安全性,具体如下:



降低延迟,针对HTTP高延迟的问题,SPDY优雅的采取了多路复用(multiplexing)。多路复用通过多个请求stream共享一个tcp连接的方式,解决了HOL blocking的问题,降低了延迟同时提高了带宽的利用率。



请求优先级(request prioritization)。多路复用带来一个新的问题是,在连接共享的基础之上有可能会导致关键请求被阻塞。SPDY允许给每个request设置优先级,这样重要的请求就会优先得到响应。比如浏览器加载首页,首页的html内容应该优先展示,之后才是各种静态资源文件,脚本文件等加载,这样可以保证用户能第一时间看到网页内容。



header压缩。前面提到HTTP1.x的header很多时候都是重复多余的。选择合适的压缩算法可以减小包的大小和数量。



基于HTTPS的加密协议传输,大大提高了传输数据的可靠性。



服务端推送(server push),采用了SPDY的网页,例如我的网页有一个sytle.css的请求,在客户端收到sytle.css数据的同时,服务端会将sytle.js的文件推送给客户端,当客户端再次尝试获取sytle.js时就可以直接从缓存中获取到,不用再发请求了。SPDY构成图:



SPDY位于HTTP之下,TCP和SSL之上,这样可以轻松兼容老版本的HTTP协议(将HTTP1.x的内容封装成一种新的frame格式),同时可以使用已有的SSL功能。



六、HTTP2.0性能惊人



HTTP/2: the Future of the Internet https://link.zhihu.com/?target=https://http2.akamai.com/demo 是 Akamai 公司建立的一个官方的演示,用以说明 HTTP/2 相比于之前的 HTTP/1.1 在性能上的大幅度提升。 同时请求 379 张图片,从Load time 的对比可以看出 HTTP/2 在速度上的优势。



七、HTTP2.0:SPDY的升级版



HTTP2.0可以说是SPDY的升级版(其实原本也是基于SPDY设计的),但是,HTTP2.0 跟 SPDY 仍有不同的地方,如下:



HTTP2.0和SPDY的区别:



HTTP2.0 支持明文 HTTP 传输,而 SPDY 强制使用 HTTPS



HTTP2.0 消息头的压缩算法采用 HPACK http://http2.github.io/http2-spec/compression.html,而非 SPDY 采用的 DEFLATE http://zh.wikipedia.org/wiki/DEFLATE



八、HTTP2.0和HTTP1.X相比的新特性



新的二进制格式(Binary Format),HTTP1.x的解析是基于文本。基于文本协议的格式解析存在天然缺陷,文本的表现形式有多样性,要做到健壮性考虑的场景必然很多,二进制则不同,只认0和1的组合。基于这种考虑HTTP2.0的协议解析决定采用二进制格式,实现方便且健壮。



多路复用(MultiPlexing),即连接共享,即每一个request都是是用作连接共享机制的。一个request对应一个id,这样一个连接上可以有多个request,每个连接的request可以随机的混杂在一起,接收方可以根据request的 id将request再归属到各自不同的服务端请求里面。



header压缩,如上文中所言,对前面提到过HTTP1.x的header带有大量信息,而且每次都要重复发送,HTTP2.0使用encoder来减少需要传输的header大小,通讯双方各自cache一份header fields表,既避免了重复header的传输,又减小了需要传输的大小。



服务端推送(server push),同SPDY一样,HTTP2.0也具有server push功能。



九、HTTP2.0的升级改造



前文说了HTTP2.0其实可以支持非HTTPS的,但是现在主流的浏览器像chrome,firefox表示还是只支持基于 TLS 部署的HTTP2.0协议,所以要想升级成HTTP2.0还是先升级HTTPS为好。



当你的网站已经升级HTTPS之后,那么升级HTTP2.0就简单很多,如果你使用NGINX,只要在配置文件中启动相应的协议就可以了,可以参考NGINX白皮书,NGINX配置HTTP2.0官方指南 https://www.nginx.com/blog/nginx-1-9-5/。



使用了HTTP2.0那么,原本的HTTP1.x怎么办,这个问题其实不用担心,HTTP2.0完全兼容HTTP1.x的语义,对于不支持HTTP2.0的浏览器,NGINX会自动向下兼容的。



十、附注



HTTP2.0的多路复用和HTTP1.X中的长连接复用有什么区别?



HTTP/1.* 一次请求-响应,建立一个连接,用完关闭;每一个请求都要建立一个连接;



HTTP/1.1 Pipeling解决方式为,若干个请求排队串行化单线程处理,后面的请求等待前面请求的返回才能获得执行机会,一旦有某请求超时等,后续请求只能被阻塞,毫无办法,也就是人们常说的线头阻塞;



HTTP/2多个请求可同时在一个连接上并行执行。某个请求任务耗时严重,不会影响到其它连接的正常执行;



服务器推送到底是什么?
服务端推送能把客户端所需要的资源伴随着index.html一起发送到客户端,省去了客户端重复请求的步骤。正因为没有发起请求,建立连接等操作,所以静态资源通过服务端推送的方式可以极大地提升速度。
为什么需要头部压缩?
假定一个页面有100个资源需要加载(这个数量对于今天的Web而言还是挺保守的), 而每一次请求都有1kb的消息头(这同样也并不少见,因为Cookie和引用等东西的存在), 则至少需要多消耗100kb来获取这些消息头。HTTP2.0可以维护一个字典,差量更新HTTP头部,大大降低因头部传输产生的流量。具体参考:HTTP/2 头部压缩技术介绍



HTTP2.0多路复用有多好?
HTTP 性能优化的关键并不在于高带宽,而是低延迟。TCP 连接会随着时间进行自我「调谐」,起初会限制连接的最大速度,如果数据成功传输,会随着时间的推移提高传输的速度。这种调谐则被称为 TCP 慢启动。由于这种原因,让原本就具有突发性和短时性的 HTTP 连接变的十分低效。
HTTP/2 通过让所有数据流共用同一个连接,可以更有效地使用 TCP 连接,让高带宽也能真正的服务于 HTTP 的性能提升。



HTTP1.1



这是一个使用了很长时间的协议,并且目前还在使用,它的前面有0.9、1.0。HTTP1.1默认是个持久连接,也就是不用频繁去创建连接,这对性能上提升是很大的,大家都知道,HTTP连接的创建是耗性能的。


以前的版本都是发一个请求,服务器回应后就会断开连接,下一个请求时会重新创建连接。显然,这种情况是必需改进的,于是有了HTTP1.1。虽然它是个长连接,但在连接中发送的多个请求还是会顺序处理。这样的话一旦有一个请求处理很久的话,那后面的请求就会被阻塞。在请求如此频繁的今天显然还是有些不太令人满意,虽然可以同时保持几个持久连接,但明显还有改进的地方。



HTTP2.0



首先,它解决了1.1的长连接会遇到阻塞的问题。它采用的是多路复用的形式去解决这个问题。什么是多路复用呢?就是一个通道可以让多条线路同时占用而不搞混。这里的作法是为每一个请求带一个编号,它样服务器方就能为请求的回应对上号了。如果一个请求时间过长,那么服务器就可以先暂停这个请求,先处理下一个请求,处理完再回来处理这个长请求,如果找回这个长请求呢,那就靠这个编号了。


除此之处,它还规定了HTTP传输的所有内容都转为二进制进行传输,以前的版本只有头部信息会转为二进制,内容体并不会。不统一总会造成额外的麻烦。比如内容是文本,而文本是有多种样式的,这样的话解析它的一方就很麻烦了,要支持你各种样式。



HTTP1.1和HTTP2.0的主要区别如下:



HTTP2.0(Hypertext Transfer Protocol Version 2)是超文本传输协议的第二版。HTTP 2.0相比于HTTP 1.x,大幅度的提升了web性能,同时向下兼容HTTP1.X协议版本。



Http2.0的核心优势有



1、采用二进制格式传输数据,而非http1.1文本格式,二进制格式在协议的解析和优化扩展上带来了跟多的优势和可能



2、对消息头采用Hpack进行压缩传输,能够节省消息头占用的网络流量,http1.1每次请求,都会携带大量冗余的头信息,浪费了很多宽带资源。



3、异步连接多路复用



4、Server Push,服务器端能够更快的把资源推送到客户端。



5、保持与HTTP 1.1语义的向后兼容性也是该版本的一个关键。


Category web