一文超干货的HTTP发展史 HTTP09 HTTP10

HTTP0.9

  1. http0.9只是一个简单的协议,只有一个GET命令,没有首部,目标用来获取HTML
  2. 服务器发送完毕,就关闭TCP连接

HTTP1.0

  1. 从单一的GET请求,增加了POST命令和HEAD命令
  2. 支持发送任何格式的内容
  3. 每次通信都必须包括头信息(HTTP header),用来描述一些元数据
  4. 新增功能还包括状态码(status code)、多字符集支持、多部分发送(multi-part type)、权限(authorization)、缓存(cache)、内容编码(content encoding)等

HTTP1.0的缺点

  1. 连接无法复用:每个TCP连接只能发送一个请求,发送数据完毕,连接就关闭,如果还要请求其他资源,就必须再新建一个连接。
  2. 队头阻塞(Head-of-line blocking):当页面中需要请求很多资源的时候,队头阻塞会导致在达到最大请求数量时,剩余的资源需要等待其它资源请求完成后才能发起请求。

HTTP1.1

  1. 长连接:HTTP1.1增加Connection字段,通过设置Keep-Alive保持TCP连接不关闭。避免每次客户端与服务器请求都要重复建立释放建立TCP连接。关闭可以在请求头中携带Connection:false来告知服务器关闭请求。
  2. 管道化(pipelining):同一个TCP连接里面,客户端可以同时发送多个请求,但服务器必须按照客户端请求的先后顺序依次回送相应的结果。
  3. 缓存处理:HTTP 1.0 中主要使用 header 里的 If-Modified-Since,Expires 来做为缓存判断的标准,HTTP 1.1则引入了更多的缓存控制策略例如 Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。
  4. 新增命令:PUT、PATCH、HEAD、 OPTIONS、DELETE。
  5. 错误通知:HTTP1.1中新增了24个错误状态响应码。

HTTP1.1的缺点

  1. 臃肿的消息首部:HTTP/1.1能压缩请求内容,但是消息首部却无法压缩,HTTP/1 在使用时,header 里携带的内容过大,在一定程度上增加了传输的成本。
  2. 队头阻塞:虽然允许复用TCP连接,但是同一个TCP连接里面,管道化要求只能按照发送顺序依次接收响应。那么前一个请求如果很耗时,那么后面的请求即使服务器已经处理完,仍会等待前面的请求处理完才开始按序返回,后面就会有许多请求排队等着。

补充:为了防止这种问题,现代浏览器会针对单个域名开启6个连接,通过各个连接分别发送请求。它实现了某种程度上的并行,但是每个连接仍会受到队头阻塞的影响。另外,这也没有高效利用有限的设备资源。

  1. 低效的TCP利用:TCP协议作为最可靠的协议之一,其核心是拥塞窗口。

传输控制协议(TCP) 的设计思路是:对假设情况很保守,并能够公平对待同一网络的不同流量的应用。它的避免拥塞机制被设计成即使在最差的网络状况下仍能起作用,并且如果有需求冲突也保证相对公平。这是它取得成功的原因之一。

拥塞窗口指在接收方确认数据包之前,发送方可以发送的TCP包的数据。(如拥塞窗口指定为1的情况,那么发送方就发出1个数据包之后,只有接收方确认了那个发出的数据包,才能发送下一个)

一般来讲,每次发送一个数据包并不是非常低效。TCP有个概念叫慢启动(Slow Start), 它用来探索当前连接对应拥塞窗口的合适大小。慢启动的设计目标是为了让新连接搞清楚当前网络状况,避免给已经拥堵的网络继续添乱。它允许发送者在收到每个确认回复后额外发送 1 个未确认包。这意味着新连接在收到1个确认回复之后,可以发送2个数据包; 在收到2个确认回复之后,可以发4个;以此类推。这种几何级数增长很快就会到达协议规定的发包数上限,这时候连接将进入拥塞避免阶段,这种机制需要往返几次才能得知最佳拥塞窗口大小,但往返几次所需的时间成本不可忽略。

现代操作系统一般会取 4~10 个数据包作为初始拥塞窗口大小。如果你把一个数据包设置为最大值下限 1460 字节(也就是最大有效负载),那么只能先发送 5840 字节(假定拥塞窗口为 4),然后就需要等待接收确认回复。

  1. 受限的优先级设置:如果浏览器针对指定域名开启了多个socket(每个都会受队头阻塞问题的困扰),开始请求资源,这时候浏览器能指定优先级的方式是有限的:要么发起请求,要么不发起。

然而 Web 页面上某些资源会比另一些更重要,这必然会加重资源的 排队效应。这是因为浏览器为了先请求优先级高的资源,会推迟请求其他资源。

但是优先级高的资源获取之后,在处理的过程中,浏览器并不会发起新的资源请求,所以服务器无法利用这段时间发送优先级低的资源,总的页面下载时间因此延长了。还会出现这样的情况:一个高优先级资源被浏览器发现,但是受制于浏览器处理的方式,它被排在了一个正在获取的低优先级资源之后。

HTTP2.0

SPDY 协议是在 TCP 协议之上。相比 HTTP/1 的文本传输格式,HTTP/2 采用二进制格式传输数据,具有更小的传输体积以及负载。

HTTP2.0通过在应用层和传输层之间增加一个二进制分层帧(http2多路复用能力的核心部分),突破了HTTP1.1的性能限制,改进传输性能。

  1. 多路复用机制:引入了二进制的分帧层机制来实现多路复用。(分帧层是基于帧的二进制协议。这方便了机器解析。请求和响应交织在一起。)多路复用很好地解决了浏览器限制同一个域名下的请求数量的问题,同时也更容易实现全速传输,毕竟新开一个 TCP 连接都需要慢慢提升传输速度。
  2. 可以设置请求的优先级:HTTP2.0里每个数据流都可以设置优先级和依赖,优先级高的数据流会被服务器优先处理和返回客户端,数据流还可以依赖其他的子数据流。(客户端的分帧层对分割块标上请求的优先级)
  3. 头部压缩:请求头压缩,增加传输效率。
  4. 服务器推送:服务器除了最初请求的响应外,服务器还可以额外向客户端推送资源,而无需客户端明确的需求。

多路复用机制的实现

所有HTTP2.0通信都在一个TCP管道,使用一个TCP长连接。下载整个资源页面,只需要一次慢启动,并且避免了竞态,浏览器发起请求,分帧层会对每个请求进行分割,将同一个请求的分割块打上相同的id编号,然后通过协议栈将所有的分割体发送给服务器,然后通过服务器的分帧层根据id编号进行请求组装,服务器的分帧层将回应数据分割按同一个回应体进行id分割回应给客户端,客户端拼装回应。

对于http2中的帧(frame),http1不是基于帧的,是文本分隔的。这样,对于http1的请求或者是响应可能有的问题:

  1. 一次只能处理一个请求或者是响应,完成之前是不能停止解析的。
  2. 无法预判解析需要多少内层。

HTTP/1 的请求和响应报文,是由起始行、首部和正文组成,换行符分隔;HTTP/2是将请求和响应数据分割成更小的帧,采用二进制编码,易于解析的。

帧结构总结 所有的帧都包含一个9 byte的帧头 + 可边长的正文不同。根据帧的类型不同,正文部分的结构也不一样。

HTTP/2 帧结构

HTTP3.0

为什么要有HTTP3.0,HTTP/2底层TCP的局限带来的问题:

由于HTTP/2使用了多路复用,一般来说,同一个域名下只需要使用一个TCP链接,但当这个连接中出现了丢包的情况(TCP协议并不是不会丢包,而是丢包后会快速重传),整个TCP都要开始等待重传,导致后面的所有数据都被阻塞。而对于HTTP/1.1来说,可以开启多个TCP连接,出现这种情况只会影响其中一个连接,剩余的TCP链接还可以正常传输数据。

谷歌基于 UDP 协议研发一种名为QUIC(全称是“快速UDP互联网连接”)的实验性网络协议。

优势

  1. 缓存当前会话的上下文:下次恢复会话的时候,只需要将之前的缓存传递给服务器,验证通过,就可以进行传输了。
  2. 多路复用:QUIC基于UDP,一个连接上的多个流之间没有依赖,即使丢包,只需要重发丢失的包即可,不需要重传整个连接。
  3. 更好的移动端表现:QUIC在移动端的表现比TCP好,因为TCP是基于IP识别连接,而QUIC是通过ID识别链接。无论网络环境如何变化,只要ID不便,就能迅速重新连上。
  4. 加密认证的根文——武装到牙齿:TCP协议头没有经过任何加密和认证,在传输过程中很容易被中间网络设备篡改、注入和窃听。

QUIC:除了个别报文,比如PUBLIC_RESET和CHLO,所有报文头部都是经过认证的,报文体都是经过加密的。所以只要对 QUIC 做任何更改,接收端都能及时发现,有效地降低了安全风险。
5. 向前纠错机制:QUIC协议有一个非常独特的特性,成为向前纠错(Foward Error Connec,FEC),每个数据包除了它本身的内容之外还包括了其他数据包的数据,因此少量的丢包可以通过其他包的冗余数据直接组装而无需重传。
向前纠错牺牲了每个数据包可以发送数据的上限,但是带来的提升大于丢包导致的数据重传,因为数据重传将会消耗更多的时间(包括确认数据包丢失,请求重传,等待新数据包等步骤的时间消耗)。

例如:我总共发送三个包,协议会算出这个三个包的异或值并单独发出一个校验包,也就是总共发出了四个包。当其中出现了非校验包丢失的情况,可以通过另外三个包计算出丢失的数据包的内容。

当然这种技术只能使用在丢失一个包的情况下,如果出现丢失多个包,就不能使用纠错机制了,只能使用重传的方式了。

如何在Chrome中启用 QUIC 协议:

  • Chrome 浏览器地址栏上输入 chrome://flags/ 。
  • Experimental QUIC protocol,将Default改为Enabled

部分内容没有进行详细书写,大佬们可以补充在评论区

相关推荐:

HTTP/2基础教程

当我们在谈论HTTP队头阻塞时,我们在谈论什么?

HTTP/1.x 的连接管理

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%