TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。
UDP(用户数据报协议)是传输层的协议,功能即为在IP的数据报服务之上增加了最基本的服务:复用和分用以及差错检测。
UDP提供不可靠服务,具有TCP所没有的优势:UDP无连接,时间上不存在建立连接需要的时延。
(DNS如果运行在TCP之上而不是UDP,那么DNS的速度将会慢很多。
HTTP使用TCP而不是UDP,是因为对于基于文本数据的Web网页来说,可靠性很重要。)
QUIC是谷歌制定的一种基于UDP的低时延的互联网传输层协议。在2016年11月国际互联网工程任务组(IETF)召开了第一次QUIC工作组会议,受到了业界的广泛关注。这也意味着QUIC开始了它的标准化过程,成为新一代传输层协议。 起初,HTTP的特点是:发一个Http Request,然后等着Http Response回来,然后再发下一个Http Request....
HTTP协议这种请求->等待响应的模式,引发了队头阻塞的问题
这些HTTP请求组成了一个队列,如果队列头部的请求的响应不回来,后面的都得等着。
解决方案:(即HTTP 升级成了 HTTP/2)
1.多建立几个TCP连接(缺点:浏览器有数量限制,同个host,最多建立6个连接)
2.多路复用(缺点:TCP层出现丢包,出现队头阻塞问题)
把每个请求和响应当成一个流(Stream) ,每个Stream都有一个ID。每个Stream可以有多个帧(Frame),Frame中保存数据。
在同一个TCP连接上,可以有多个多个帧混合着在“流动”。
HTTP 一下子发出3个请求, 它们的Stream次序是 1, 2, 3
但是返回的Stream次序是 2,1, 3, 1 , 次序乱了。
但是没关系,有Stream ID做关联,浏览器很容易知道请求和响应的对应关系。
站在TCP的角度看, 它不会意识到HTTP层有Stream的存在,一旦TCP层出现丢包,依然会出现队头阻塞的问题!
现在浏览器可以直接使用TCP#1 中的 b.js, 但是由于TCP#2丢了,按照TCP协议的要求,TCP#3中的数据是不能使用的, 虽然其中的数据是完整的h.css,还必须等待TCP#2重传。
问题的本质就是站在TCP的视角看,它看到数据是没有含义的二进制流而已。
如果修改一下TCP协议,让他理解这些“Stream”呢?
不行,TCP是在操作系统内核中实现的,想改TCP就得改操作系统,然后部署到全世界所有的网络设备上,这就难了。
所以现在只能调整一下操作系统中网络的参数而已。
既然改不了现有的TCP, 那我们就创造一个新的协议出来,让这个新协议能意识到“Stream”的存在
这个新协议,就是Google提出的QUIC!
如果浏览器收到了QUIC #1, #3, #4, 但是QUIC #2丢失了, 会发生什么情况呢?
#4 可以暂时保存,等待 #2的重新传输。
虽然QUIC不知道Stream中传输的数据到到底是什么含义,但是通过引入Stream , QUIC彻底解决了队头阻塞的问题! 当然,由于Stream的概念下移到了QUIC中,那HTTP中的Stream就不需要了。
HTTP/2就升级成了HTTP/3。
不过, QUIC是基于UDP实现的,TCP的那些优秀特性,它不得不重新实现一遍了
QUIC不在操作系统内核中,意味着应用程序可以对它任意定制,例如轻松地控制各种拥塞算法的实现。
QUIC作为新协议,除了上面说的可以解决队头阻塞问题之外,还有很多优点:
1.减少RTT时间 2. 改善拥塞控制 3. 连接迁移 4. 集成TLS,更加安全
小结:TCP协议已经统治了世界50年,基于TCP的HTTP也30多岁了,在新的环境,它们的弊端逐渐暴露,一个突出的问题就是HTTP和TCP的队头阻塞问题,QUIC和HTTP/3有可能是解决之道。
不过想替换TCP可不是那么简单的事情,2021年6月IETF 才发布了QUIC的规范RFC9000,根据w3techs的统计,至今只有5.8%的网站在使用QUIC,主要是Google的网站,QUIC任重而道远。