HTTP协议进化史

前言

HTTP,其自1990年诞生之初便是万维网交换超文本文档的首选应用层协议,发展至今已经经过了几次重大的版本升级,HTTP3便是当下最新的版本。在HTTP3之前,无论HTTP协议如何升级,其内部所依赖的是可靠的、面向连接的TCP协议,在升级为HTTP3之后使用UDP替代了TCP的协议。众所周知UDP协议的传输速率是高于UDP的,毕竟TCP是“可靠的“协议,其特性导致在数据传输过程中会产生一定的时间消耗,也正是通过损耗效率为代价换取可靠的数据传输。

一、什么是QUIC

QUIC(Quick UDP Internet Connection,快速UDP网络连接,与单词 “quick” 谐音)是谷歌提出的一种基于UDP的可多路复用的安全传输协议,并于2012年部署,在2013年随着实验的扩大而公开宣布,同时向IETF进行了描述。QUIC对 HTTP/2 语义做了优化,提供了等价于HTTP/2 的多路复用和流量控制、TLS 的安全机制,相当于实现了TCP 的连接语义、可靠性和拥塞控制等特性。

二、HTTP协议发展历程

在这里插入图片描述

  • HTTP 0.9(1991年)只支持get方法的单行协议

  • HTTP 1.0(1996年)更加完整、接近现代化的协议:请求方法、请求头、状态码…

  • HTTP 1.1(1997年)标准化协议:新增请求方法、持久连接、管道、Host头…

  • HTTP 2.0(2015年)更优异的表现:二进制、多路复用、头部压缩、服务器推送…

  • HTTP 3.0(2018年)构建高效网络:QUIC协议

2.1 HTTP/0.9-单行协议

历史上第一个有记载的HTTP标准,它定义了当时客户端发起请求、服务端响应请求的通信模式。该协议极其简单,其组成只有一行——GET + 请求路径,服务端在收到请求返回处理结果后便会关闭TCP连接。

2.2 HTTP/1.0-构建可拓展性

1996年5月,一个更加完整、更加接近我们目前对 HTTP 认知的版本发布—HTTP1.0,该版本已经包含了我们现在所熟知的很多概念:请求方法、请求头、状态码…此时的请求/响应结构已经和现在的请求基本一致了,对比HTTP/0.9,HTTP/1.0引入很多新的内容,如:

  • 增加了 HEAD、POST
  • 引入了 Header 的概念,让 HTTP 处理请求和响应更加
  • 引入了协议版本号(包括在请求头内)
  • content-type字段的使用增加了传输的数据格式(如json、image),不再仅限于文本
  • 增加了响应状态码,标记可能的错误原因

然而,由于HTTP1.0不支持长连接,每次请求都需要建立新的TCP连接,无疑会增加握手开销,降低传输效率。同时HTTP/1.0所保持的TCP连接每次只能处理一个请求,虽然可以一次性接受多个请求,但仍然需要按请求顺序依次有序返回处理结果,如此下来当前面的请求处理异常很容易导致其余请求阻塞。

2.3 HTTP/1.1-标准化协议

前面提到了HTTP/1.0 每进行一次通信,都需要重复建立连接、传输数据和断开连接三个步骤。当一个页面引用了较多的外部文件时,这个建立连接和断开连接的过程就会导致网络请求开销急剧增大。

为了解决这个问题,HTTP/1.1 增加了一个创建持久连接的方法。主要实现是当一个连接传输完成时,并不是马上进行关闭,而是继续复用它传输其他请求的数据,这个连接保持到浏览器或者服务器要求断开连接为止。

HTTP1.1部分新特如下:

  • 增加了 PUT、DELETE 、OPTIONS、TRACE方法
  • 支持并默认开启持久连接(Connection:keep-alive),持久连接即为TCP连接在服务器发送完数据默认不关闭,保持连接状态
  • 引入管道机制(Pipelining)。即在同一个TCP连接里面,客户端可以同时发送多个请求
  • 允许响应数据分块(chunked),利于传输大文件
  • 增加Host头,即指定请求的主机名和端口,使得不同域名可以配置在同一台服务器上
  • 支持更多的缓存处理如:E-tag,If-Match,If-None-Match等

2.4 HTTP/2-为了更优异的表现

HTTP/2 的前身是由 google 主导开发的 SPDY,SPDY并不是一个标准协议,但SPDY的开发组推动SPDY成为正式标准,而成为了互联网草案,后来SPDY并没有单独成为正式标准,不过SPDY开发组的成员全程参与了HTTP/2的制定过程,为了达到预期的性能优化,HTTP/2 中新增了二进制分帧层,这与现有 HTTP/1.1 协议的服务器及客户端是不兼容的,所以版本号直接从1升级到了2。

HTTP/2部分新特性如下:

  • HTTP/2 采用二进制协议替代原本的文本,不再可读。
  • 多路复用,并行的请求可以在同一TCP链接中处理,移除了 HTTP/1.x 中顺序和阻塞的约束。
  • 使用压缩算法压缩请求头header,减少数据传输量。
  • 允许服务器主动向客户端推送数据,无需客户端明确请求。
  • 数据流中可以设置优先级,以此觉得客户端或服务端采取不同优先级处理数据流。
    二进制传输
  • HTTP/2并没有改变传统HTTP语义:如请求方法、状态码、请求头等,为了突破限制提高传输小路,HTTP/2在传统的HTTP协议与TCP协议之间加入了二进制分帧层,传统的HTTP协议采用的文本协议进行传输,而从HTTP/2开始改为二进制传输。

在该层中,HTTP/2会将所有的请求信息分割为更小的信息单元(消息、帧),同时对它们使用二进制编码,将请求头的新增封装至Hearders帧中,请求体中的数据封装至Data帧中。随后,以帧的形式在连接中进行数据交换。
在这里插入图片描述

多路复用

HTTP/2新增了几个概念,流(stream,处于TCP连接中的双向字节流,即每个请求),帧(HTTP2中通信过程中的最小单位,其中包含当前请求中的数据信息),消息(一系列数据帧组成的完整数据)。HTTP/2通过二进制帧的形式实现所有请求都在一个TCP连接中传输:HTTP/2将通信单位缩小为帧,单个TCP连接中可以承载诸多的数据流,每一个数据流以消息的形式进行传输,消息可以拆解为多个数据帧,而数据帧可以乱序在连接中传输,接收方根据数据帧中的不同的流ID将数据帧进行归类到不同的请求中去。
在这里插入图片描述

这里可以看出多个流之间没有了顺序关系,不需要排队等待,降低了延迟,大幅度提高了连接的利用率。

头部压缩

在传统的HTTP请求中请求和响应都是由状态行、请求头、消息体三部分构成,一般情况下消息头都会经过压缩,降低数据大小,但是状态行和请求头信息并没有经过压缩。然而如何的Web功能逐渐复杂,请求量不断增大,头部携带信息的数量也相应的增加,导致传输量增大。为此HTTP2中使用HPACK算法压缩头部信息,降低了数据体积,提高传输速度。

HTTP2相较于HTTP1.x已经优化了很多,但是,科技永不止步,HTTP/2依旧存在瓶颈—TCP。由于HTTP/2依旧是基于TCP,那么当TCP传输中出现丢包时,整个TCP连接将会阻塞,那么其余的所有请求都需要等待请求重传,造成TCP层的队头阻塞问题况。除此之外,当连接迁移时TCP需要重新建立连接,那么该过程需要重复握手、传输、处理等环节,无疑都会影响传输效率,为此,HTTP/3从根本上解决了这个问题—抛弃TCP。

2.5 HTTP/3-构建高效网络

前面提到了,TCP协议的特性会造成队头阻塞,所有HTTP3的版本在传输层采用UDP代替TCP的形式,避开了TC带来的队头阻塞问题,同时通过基于UDP的QUIC协议达到类似TCP的拥塞控制、连接管理等特性,将原本”不可靠“的UDP转变为”可靠"的UDP协议,提高传输效率的同时保证数据传输的可靠性。
在这里插入图片描述

其实提出修改TCP协议而非使用UDP替代这个观点,未尝不是一种办法,但是仔细想想,TCP协议诞生时间之久,影响之广泛,导致其早已充斥在各种硬件设备之中。所以如果需要对TCP协议进行修改,那么对于历史硬件设备而言无疑无法做到支持,替换所有的历史设备成本大到离谱无法想象,因此这个提议实现起来的话并不太现实。

也是基于这个原因,Google 就更起炉灶搞了一个基于 UDP 协议的 QUIC 协议,并且使用在了 HTTP/3 上,HTTP/3 之前名为 HTTP-over-QUIC,从这个名字中我们也可以发现,HTTP/3 最大的改造就是使用了QUIC。

三、QUIC协议关键特性

择其善者而从之,其不善者而改之,既然Google选择了QUIC,那么必然是由于其的一些特性符合构建更加高效的网络的思路,在此我们列举一下QUIC的关键特性,从这些特性触发,作为切入点了解QUIC。

QUIC的关键特性如下:

  • 减少TLS握手,降低连接延时
  • 更优异的多路复用
  • 更好的连接迁移,对于移动设备网络要求更友好
  • 改进的拥塞控制
  • 前向纠错

减少TLS握手(0RTT连接)
RTT(Round-Trip Time)即数据包一来一回的时间消耗,是衡量网络建立连接的常用指标,其包含三部分(往返传播时延、网络设备内排队时延、应用程序数据处理时延)。

以目前应用最广泛的TLS 1.2而言,其建立连接需要2个RTT。对于非首次建连,可以选择启用会话重用,则可缩小握手时间到1个RTT,而QUIC协议实现了最快0-RTT握手,首次是1RTT。

对于数据量小的请求而言,单一次的请求握手就占用了大量的时间,对于用户体验的影响比较大。同时,在用户网络不佳的情况下,RTT延时所占的比重也会变得较高,增加整体请求开销;
在这里插入图片描述

更优异的多路复用
TCP的滑动窗口机制导致在出现丢包或者确认超时的情况下窗口无法移动,导致该连接下的所有请求流都被阻塞。HTTP/2中的多路复用解决了HTTP层面的队头阻塞,但是依旧无法避免TCP层的队头阻塞,为此,QUIC协议为为每一个请求留都分配了一个独立的滑动窗口,那么A请求流出现的丢包将不会影响到其余请求留的数据收发。
在这里插入图片描述

在并发请求中,QUIC解决了队头阻塞问题,但是对于单条数据流,依旧存在该问题。

连接迁移
当客户端切换网络时(如WIFI切换为移动网络),和服务器的连接并不会断开,仍然可以正常通信。这对于TCP而言是不可能实现的,TCP 连接是由五元组标识的(源 IP,源端口,目的 IP,目的端口,协议号),只要其中任意部分发生改变,TCP就需要建立重新连接。

而基于UDP的QUIC协议不需要五元组标识连接,而是基于Connetction ID 进行识别连接,当源地址改变时,Connetction ID不变,服务器也是通过Connection ID来标识一个QUIC连接的信息,即使切换了网络,新网络还可以通过之前的Connection ID来继续利用之前的连接,无需新建连接,依旧可以保持连接,正常进行数据的收发。
在这里插入图片描述

改进拥塞控制
TCP 的拥塞控制实际上包含了四个算法:慢启动,拥塞避免,快速重传,快速恢复,QUIC协议在此之上进行了优化,如:可插拔式设计,对于每个原始包,增加一个新的序列号,通过序列号QUIC能够区分是重传包还是原始包,避免传输模糊问题;QUIC还携带有收到数据包与发出ACK之间的时延数据,可以更加精准的计算RTT等。

前向纠错:
前向纠错也叫前向纠错码Forward Error Correction 简称FEC ,其目的是增加在通讯过程中提高数据的可信度,在单向通讯信道中,一旦错误被发现,其接收器将无权再请求传输。而QUIC每发送一组数据就对这组数据进行异或运算,并将结果作为一个FEC包发送出去,接收方收到这一组数据后根据数据包和FEC包即可进行校验和纠错。

四、写在最后

本次浅析从http0.9到http3做了简单的介绍,以不同版本协议间的异同作为切入点分析QUIC的优势及特性,当然,这次的分析对于QUIC本身而言只是微乎其微的一小部分,QUIC 的魅力等待着大家更多的发掘。

文中如有错误、不到位的地方,欢迎大家批评指正,互相学习~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值