从HTTP的发展史,彻底掌握HTTP——第三篇,了解HTTP3.0的颠覆

309 阅读7分钟

前言

大家好,我是抹茶。接着上篇# 从HTTP的发展史,彻底掌握HTTP——第二篇,来自HTTP2.0的进化我们继续研究HTTP/ 3.0。

上篇提到,为了解决TCP的慢启动和队头堵塞问题,HTTP/2.0一个域名只使用一个 TCP 长连接来传输数据,同时增加了二进制分帧层来对请求进行分帧,从而使得服务器可以对优先级高的请求优先响应。但是HTTP/2.0依旧是基于TCP的,仍存在数据包级别的队头堵塞问题。本文将分析基于当下的TCP连接存在的问题,思考HTTP/ 3.0应如何设计和应对当前的困境。

TCP的队头堵塞

HTTP/1.0的数据传输过程

1.1正常传输过程.png 如上图所示,HTTP/1.1会将数据按顺序排列,一个个有条不紊地从发送端到达接收端。数据包的接收顺序是按照发送顺序来的。

如果丢包,整个发送的过程会暂停,直到丢包的数据重传完成。

1.1传输丢包过程.png

在业界,TCP 传输过程中,由于单个数据包的丢失而造成的阻塞称为TCP上的队头阻塞。 在HTTP/1.1中,谷歌浏览器同一个域名最多同时支持6个TCP链接。

HTTP/2.0的数据传输过程

HTTP/2.0对于同一个域名,只会开启一个TCP连接。所有的数据包通过二进制分帧成再细分成帧,每一帧都会有id号,传输和接收的过程可以是无序的,在接收侧会根据id将这些数据组装起来。

2.0的协议栈.png

传输过程的数据包可以抽象理解成下图所示:

2.0正常传输过程.png

如果过程中有数据丢包,整个数据传管道都会被中断,直到包重传完成,这是因为TCP保证数据完整性的重传机制导致的。

在HTTP/1.1的时候,一个域名可以有6个TCP,也就是6个数据传输的管道,如果其中一条有丢包,其他五条还可以进行数据传输。在HTTP/2.0的时候,一个域名只会有一个TCP连接,如果有丢包,整个数据传输都会暂停。所以随着丢包率的增加,HTTP/2.0 的传输效率也会越来越差。有测试数据表明,当系统达到了 2% 的丢包率时,HTTP/1.1 的传输效率反而比 HTTP/2.0 表现得更好。

TCP的延迟问题

除了队头堵塞,TCP建立连接时的网络延迟也是影响传输效率的一个重要因素。

网络延迟又称为RTT(Round Trip Time)。我们把从浏览器发送一个数据包到服务器,再从服务器返回数据包到浏览器的整个往返时间称为RTT。RTT是反映网络性能的一个重要指标。

RTT.png

那建立TCP连接需要多少RTT呢? 1.TCP连接需要经历3次握手,所以是1.5个RTT。 2.如果是HTTPS,使用TLS协议进行安全传输,而TLS也需要一个握手过程,TLS有两个版本————TLS1.2和TLS1.3,每个版本建立连接需要花费的时间不同,大致需要1 ~ 2个RTT。

综上所述,建立连接需要花费3 ~ 4个 RTT。如果浏览器和服务器的物理距离较近,那么1个RTT的时间可能在1毫秒以内,也就是总共要消耗掉30 ~ 40毫秒。如果服务器较远,1个RTT就需要100毫秒以上了,这种情况下整个握手过程需要300 ~ 400毫秒,用户会明显的感受到卡顿。

抹茶最近用UniCloud开发小程序,明显感受到接口慢,一看300+毫秒。

image.png

对比掘金的接口响应,还有很大进步空间,盲猜原因是UniCloud提供的云服务器距离远。

image.png

HTTP/ 3.0要解决的问题

如何在丢包情况下,避免丢头堵塞问题,又能高效连接连接呢?
能否改进TCP层?毕竟卡点在这里。

答案是非常困难。原因有两点。
1.中间设备僵化
互联网是由多个网络互联的网状结构,为了能够保障互联网的正常工作,我们需要在互联网的各种搭建各种设备,这些设备就被称为中间设备。

中间设备有很多种乐行,并且每种设备都有自己目的。这些设备包括了路由器、防火墙、NAT、交换机等。它们通常依赖一些很少升级的软件,这些软件使用了大量的TCP特性,这些功能被设置后就很少更新了。

所以,如果在客户端升级了TCP协议,但是当新协议的数据包经过这些中间设备时,它们可能不理解包的内容,于是这些数据就会被丢掉。这就是中间设备僵化,它是阻碍TCP更新的一大障碍。

2.操作系统僵化
TCP协议都是通过操作系统内核来实现的,应用程序只能使用不能修改。通常操作系统的更新都滞后于软件的更新,因此想要自由地更新内核中的TCP协议也是非常困难的。

从上面的分析过程来看,要修改TCP的重传机制并不现实,那我们是不是可以创建新的协议呢?这些中间设备只认识TCP和UDP,如果采用新的协议,新协议在这些设备同样不被很好支持。

所以HTTP/3.0的采用了一个折中的方案——UDP协议,基于UDP实现了类似于TCP的多路复用、传输可靠性等功能,这套功能被称为QUIC协议

关于HTTP/2.0与HTTP/3.0协议栈的对比,如下图所示

HTTP2与HTTP3的协议栈.png

从上面可以看到,QUIC协议集合了以下几点功能:

1. 实现了类似TCP的流量控制、传输可靠性的功能
虽然UDP不提供可靠性的传输,但QUIC在UDP的基础之上增加了一层来保证数据可靠性传输。它提供了数据包重传、拥塞控制以及其他一些TCP中存在的特性。

2. 集成了TLS加密功能
目前QUIC使用的是TLS1.3,相较于早期版本TLS1.3有更多的优点,其中最重要的一点是减少了握手所花费的RTT个数。

3. 实现了HTTP/2.0的多路复用功能
和TCP不同,QUIC实现了在同一物理连接上可以有多个独立的逻辑数据流(如下图)。实现了数据流的单独传输,就解决了TCP中的队头阻塞问题。

3.0正常传输过程.png

4. 实现了快速握手
由于QUIC是基于UDP的,所以QUIC可以实现使用0-RTT或者1-RTT来建立连接,这意味着QUIC可以用最快的速度来发送和接收数据,可以大大提升首次打开页面的速度。

HTTP/3的挑战

从技术层面的构想来说,HTTP/3是个完美的协议。但是要将HTTP/3应用到实际环境中依然面临着诸多严峻的挑战。这些挑战主要来自于三个方面

1.浏览器端和服务器端都没有对HTTP/3提供比较完整的支持。

Chrome虽然在数年前就开始支持Google版本的QUIC,但是这个版本的QUIC和官方的QUIC存在着非常大的差异。

2.部署HTTP/3 存在非常大问题

因为系统内核对UDP的优化远远没有达到TCP的优化程度,这也是阻碍QUIC的一个重要原因。

3.中间设备的僵化

这些设备对UDP的优化程度远远低于TCP,据统计使用QUIC协议,大约有3%~7%的丢包率。

总结

本文从HTTP/1.1到HTTP/2.0对数据的传输过程进行分析,了解这些版本影响传输效率的原因,如TCP的队头堵塞、TCP建立连接的延迟,再分析能否通过修改TCP协议或者创建新的协议去规避这些问题,答案是不能,因为中间设备的僵化和操作系统的僵化,改动成本很大,需要整个互联网的节点都配合修改。

因为这些中间设备只支持UDP和TCP,所以HTTP/3 试图基于UDP实现TCP的安全传输,但是由于中间设备僵化、系统内核对UDP的优化程度远远低于TCP、服务器和浏览器当前都没完整支持QUIC,HTTP/3改动到了底层协议,面临挑战,它的推广将是一个很缓慢的过程。