HTTP/2作错了什么?刚刚辉煌2年就要被弃用了!?

GitHub 19k Star 的Java工程师成神之路,不来了解一下吗!git

GitHub 19k Star 的Java工程师成神之路,真的不来了解一下吗!github

GitHub 19k Star 的Java工程师成神之路,真的真的不来了解一下吗!浏览器

最近一段时间以来,关于HTTP/3的新闻有不少,愈来愈多的国际大公司已经开始使用HTTP/3了。安全

因此,HTTP/3已是箭在弦上了,全面使用只是个时间问题,那么,做为一线开发者,咱们也是时候了解下到底什么是HTTP/3,为何须要HTTP/3了。性能优化

因而,我准备开始写这篇文章,可是要想把HTTP/3的事情说清楚,必定绕不过的问题就是HTTP/2,因此写着写着,篇幅愈来愈多,因而我就把他们分红了上下两篇。服务器

这一篇咱们主要来回顾下HTTP/2,而后再来重点看一下HTTP/2存在哪些问题,为何要被弃用。网络

HTTP/2 辉煌不在?

虽然HTTP/2标准在2015年5月就以RFC 7540正式发表了,而且多数浏览器在2015年末就支持了。tcp

可是,真正被普遍使用起来要到2018年左右,可是也是在2018年,11月IETF给出了官方批准,承认HTTP-over-QUIC成为HTTP/3。post

2018年的时候,我写过一篇文章介绍《HTTP/2究竟是什么?》,那时候HTTP/2仍是个新技术,刚刚开始有软件支持,短短两年过去了,如今HTTP/3已经悄然而至了。性能

根据W3Techs的数据,截至2019年6月,全球也仅有36.5%的网站支持了HTTP/2。因此,可能不少网站还没开始支持HTTP/2,HTTP/3就已经来了。

因此,对于不少网站来讲,或许直接升级HTTP/3是一个更加正确的选择。

回顾 HTTP/2

在阅读本文以前,强烈建议你们先阅读下《HTTP/2究竟是什么?》这篇文章,这里面介绍了HTTP的历史,介绍了各个版本的HTTP协议的诞生的背景。

当你读到这里的时候,我默认你们对HTTP/2有了必定的基本了解。

咱们知道,HTTP/2的诞生,主要是为了解决HTTP/1.1中的效率问题,HTTP/2中最核心的技术就是多路复用技术,即容许同时经过单一的HTTP/2.0链接发起多重的请求-响应消息。

同时还实现了二进制分帧、header压缩、服务端推送等技术。

从HTTP/1.0诞生,一直到HTTP/2,在这24年里,HTTP协议已经作过了三次升级,可是有一个关键的技术点是不变的,那就是这全部的HTTP协议,都是基于TCP协议实现的。

流水的HTTP,铁打的TCP。这是由于相对于UDP协议,TCP协议更加可靠。

虽然在HTTP/1.1的基础上推出HTTP/2大大的提高了效率,可是仍是有不少人认为这只是个"临时方案",这也是为何刚刚推出没多久,业内就开始大力投入HTTP/3的研发与推广了。

而这背后的深层次缘由也正是由于他仍是基于TCP协议实现的。TCP协议虽然更加可靠,可是仍是存在着必定的问题,接下来具体分析下。

HTTP/2 问题

队头阻塞

队头阻塞翻译自英文head-of-line blocking,这个词并不新鲜,由于早在HTTP/1.1时代,就一直存在着队头阻塞的问题。

可是不少人在一些资料中会看到有论点说HTTP/2解决了队头阻塞的问题。可是这句话只对了一半。

只能说HTTP/2解决了HTTP的队头阻塞问题,可是并无解决TCP队头阻塞问题!

若是你们对于HTTP的历史有必定的了解的话,就会知道。HTTP/1.1相比较于HTTP/1.0来讲,最主要的改进就是引入了持久链接(keep-alive)。

所谓的持久链接就是:在一个TCP链接上能够传送多个HTTP请求和响应,减小了创建和关闭链接的消耗和延迟。

引入了持久链接以后,在性能方面,HTTP协议有了明显的提高。

另外,HTTP/1.1容许在持久链接上使用请求管道,是相对于持久链接的又一性能优化。

所谓请求管道,就是在HTTP响应到达以前,能够将多条请求放入队列,当第一条HTTP请求经过网络流向服务器时,第二条和第三条请求也能够开始发送了。在高时延网络条件下,这样作能够下降网络的环回时间,提升性能。

可是,对于管道链接仍是有必定的限制和要求的,其中一个比较关键的就是服务端必须按照与请求相同的顺序回送HTTP响应。

这也就意味着,若是一个响应返回发生了延迟,那么其后续的响应都会被延迟,直到队头的响应送达。这就是所谓的HTTP队头阻塞

可是HTTP队头阻塞的问题在HTTP/2中获得了有效的解决。HTTP/2废弃了管道化的方式,而是创新性的引入了帧、消息和数据流等概念。客户端和服务器能够把 HTTP 消息分解为互不依赖的帧,而后乱序发送,最后再在另外一端把它们从新组合起来。

由于没有顺序了,因此就不须要阻塞了,就有效的解决了HTTP对队头阻塞的问题。

可是,HTTP/2仍然会存在TCP队头阻塞的问题,那是由于HTTP/2其实仍是依赖TCP协议实现的。

TCP传输过程当中会把数据拆分为一个个按照顺序排列的数据包,这些数据包经过网络传输到了接收端,接收端再按照顺序将这些数据包组合成原始数据,这样就完成了数据传输。

可是若是其中的某一个数据包没有按照顺序到达,接收端会一直保持链接等待数据包返回,这时候就会阻塞后续请求。这就发生了TCP队头阻塞

HTTP/1.1的管道化持久链接也是使得同一个TCP连接能够被多个HTTP使用,可是HTTP/1.1中规定一个域名能够有6个TCP链接。而HTTP/2中,同一个域名只是用一个TCP链接。

因此,在HTTP/2中,TCP队头阻塞形成的影响会更大,由于HTTP/2的多路复用技术使得多个请求实际上是基于同一个TCP链接的,那若是某一个请求形成了TCP队头阻塞,那么多个请求都会受到影响。

TCP握手时长

一提到TCP协议,你们最早想到的必定是他的三次握手与四次关闭的特性。

由于TCP是一种可靠通讯协议,而这种可靠就是靠三次握手实现的,经过三次握手,TCP在传输过程当中能够保证接收方收到的数据是完整,有序,无差错的。

可是,问题是三次握手是须要消耗时间的,这里插播一个关于网络延迟的概念。

网络延迟又称为 RTT(Round Trip Time)。他是指一个请求从客户端浏览器发送一个请求数据包到服务器,再从服务器获得响应数据包的这段时间。RTT 是反映网络性能的一个重要指标。

咱们知道,TCP三次握手的过程客户端和服务器之间须要交互三次,那么也就是说须要消耗1.5 RTT。

另外,若是使用的是安全的HTTPS协议,就还须要使用TLS协议进行安全数据传输,这个过程又要消耗一个RTT(TLS不一样版本的握手机制不一样,这里按照最小的消耗来算)

那么也就是说,一个纯HTTP/2的链接,须要消耗1.5个RTT,若是是一个HTTPS链接,就须要消耗3-4个RTT。

而具体消耗的时长根据服务器和客户端之间的距离则不尽相同,若是比较近的话,消耗在100ms之内,对于用来讲可能没什么感知,可是若是一个RTT的耗时达到300-400ms,那么,一次链接创建过程总耗时可能要达到一秒钟左右,这时候,用户就会明显的感知到网页加载很慢。

升级TCP是否可行?

基于上面咱们提到的这些问题,不少人提出来讲:既然TCP存在这些问题,而且咱们也知道这些问题的存在,甚至解决方案也不难想到,为何不能对协议自己作一次升级,解决这些问题呢?

其实,这就涉及到一个"协议僵化"的问题。

这样讲,咱们在互联网上浏览数据的时候,数据的传输过程实际上是极其复杂的。

咱们知道的,想要在家里使用网络有几个前提,首先咱们要经过运行商开通网络,而且须要使用路由器,而路由器就是网络传输过程当中的一个中间设备。

中间设备是指插入在数据终端和信号转换设备之间,完成调制前或解调后某些附加功能的辅助设备。例如集线器、交换机和无线接入点、路由器、安全解调器、通讯服务器等都是中间设备。

在咱们看不到的地方,这种中间设备还有不少不少,一个网络须要通过无数个中间设备的转发才能到达终端用户。

若是TCP协议须要升级,那么意味着须要这些中间设备都能支持新的特性,咱们知道路由器咱们能够从新换一个,可是其余的那些中间设备呢?尤为是那些比较大型的设备呢?更换起来的成本是巨大的。

并且,除了中间设备以外,操做系统也是一个重要的因素,由于TCP协议须要经过操做系统内核来实现,而操做系统的更新也是很是滞后的。

因此,这种问题就被称之为"中间设备僵化",也是致使"协议僵化"的重要缘由。这也是限制着TCP协议更新的一个重要缘由。

因此,近些年来,由IETF标准化的许多TCP新特性都因缺少普遍支持而没有获得普遍的部署或使用!

放弃TCP?

上面提到的这些问题的根本缘由都是由于HTTP/2是基于TPC实现致使的,而TCP协议自身的升级又是很难实现的。

那么,剩下的解决办法就只有一条路,那就是放弃TCP协议。

放弃TCP的话,就又有两个新的选择,是使用其余已有的协议,仍是从新创造一个协议呢?

看到这里,聪明的读者必定也想到了,创造新的协议同样会受到中间设备僵化的影响。近些年来,由于在互联网上部署遭遇很大的困难,创造新型传输层协议的努力基本上都失败了!

因此,想要升级新的HTTP协议,那么就只剩一条路能够走了,那就是基于已有的协议作一些改造和支持,UDP就是一个绝佳的选择了。

总结

由于HTTP/2底层是采用TCP协议实现的,虽然解决了HTTP队头阻塞的问题,可是对于TCP队头阻塞的问题却无能为力。

TCP传输过程当中会把数据拆分为一个个按照顺序排列的数据包,这些数据包经过网络传输到了接收端,接收端再按照顺序将这些数据包组合成原始数据,这样就完成了数据传输。

可是若是其中的某一个数据包没有按照顺序到达,接收端会一直保持链接等待数据包返回,这时候就会阻塞后续请求。这就发生了TCP队头阻塞

另外,TCP这种可靠传输是靠三次握手实现的,TCP三次握手的过程客户端和服务器之间须要交互三次,那么也就是说须要消耗1.5 RTT。若是是HTTPS那么消耗的RTT就更多。

而由于不少中间设备比较陈旧,更新换代成本巨大,这就致使TCP协议升级或者采用新的协议基本没法实现。

因此,HTTP/3选择了一种新的技术方案,那就是基于UDP作改造,这种技术叫作QUIC。

那么问题来了,HTTP/3是如何使用的UDP呢?作了哪些改造?如何保证链接的可靠性?UDP协议就没有僵化的问题了吗?

这些问题咱们在下一篇中深刻分析。敬请期待!

参考资料:

https://http3-explained.haxx.se/

https://baike.baidu.com/item/中间设备/3688874

https://time.geekbang.org/column/article/150159

https://juejin.cn/post/6844903853985366023

https://time.geekbang.org/column/article/279164

相关文章
相关标签/搜索