web 可靠传输主要依赖TCP协议,但多年过去,更优秀的协议会诞生,其中很可能会取代TCP的协议叫QUIC
。
QUIC
跟TCP
有一些重要差别,导致HTTP 2
要兼容QUIC
比较困难,所以才搞出一个HTTP 3
来适配QUIC
。
给一个示意图:
TCP
设计之初并不是为了效率最大化,更多是可靠性考虑。比如握手机制,但握手需要预先耗费一个RTT。
另外,TCP
连接不支持多文件传输,同一个连接只传递一个文件。当你希望减少连接数,用一个连接同时传输多个文件时,对TCP
来说这多个文件是捆绑在一起的一个文件,或一个流,因此,多文件传输时某一个文件发生丢包,TCP
就认为它眼里的整个文件不完整,大家一起阻塞。这种情况称为队头阻塞。
针对TCP
的已知问题,可以做一些扩展来优化,但是,实际部署很难,客户端和服务器升级还比较简单,但很多网络设施,比如防火墙,路由器,代理服务器等,他们普遍都有一些对TCP
自定义的实现,因此不兼容新的扩展升级。
结果就是,需要新的协议直接替换TCP
,而不是升级它。替换的协议就是QUIC
。我们并不真的需要一个HTTP 3
,更多的是需要一个TCP
的进化版本,而为了兼容它,才搞了一个HTTP 3
,所以,HTTP 3
的主要新特性都来自于QUIC
。
关于QUIC
从图中可以看到,QUIC
下层是UDP
。其实QUIC
作为一个单独的传输层协议,底层可以直接是IP
层,但这样做的话,上面提到的网络中间设施都要升级才能支持QUIC
,而UDP
是一个广泛支持的应用层协议,QUIC
部署到UDP
上能让网络中间设施继续兼容,网络的中间设施不需要应用层的协议,他们的传输只需要到应用层那一层或者只需要到IP
层。
UDP
是最最基础的传输层协议,它只负责传数据,其他任何手段都没有,而其他可靠性的手段全都交给连接两头的终端里面的QUIC
协议来保证。
QUIC
是可靠传输协议,也实现了TCP
那些保证可靠的特性,但QUIC
用了更高明的手段来实现,所以效率更高。
QUIC
的改进
QUIC
有下面一些主要改进:
1. QUIC
直接融合了TLS
QUIC
几乎加密了所有头部信息,只留下传输必须的头部信息。而TCP
基于TLS
的实现只加密了HTTP
的内容。所以,QUIC
有更高安全性。
QUIC
把传输和加密的握手融合在一起,减少了初始握手时间。TCP
基于TLS
的方式需要TCP
和TLS
分别做握手操作。
QUIC
有更好的可扩展性,因为它是完全加密的,中间设施不能观察和解释到它里面的内容,它们只知道是UDP
在传输一些内容而已,所以,QUIC
有更新时,只需要终端设施更新一下协议就行,不需要更新所有的中间设施。
当然,上面的特性也导致了一些问题:
公司和运营商无法拦截某些想拦截的流量,因为解析不了QUIC
的信息,无法做判断。
QUIC
有更高的加密开销。
2. QUIC
能区分同一个连接中不同流
用同一个连接传输多个文件,QUIC
知道哪个包属于哪个文件,当有一个包丢失时,不会阻塞其他不相关文件。
3. QUIC
支持连接迁移
客户端跟服务器建立连接,本质上就是经过握手,然后客户端的IP地址,客户端的端口号,服务端的IP地址,服务端的端口号,这4元素就定义了一个连接。任何一个值发生变化,都要重新建立连接。当客户端从WiFi切换到4G,它的IP地址肯定发生变化,之前的连接失效,需要重新建立连接。
QUIC
增加了连接标识符,用来标识一个连接,这个字段不会被加密。就算标识一个连接的重要4元素发生变化,也可以用连接标识符识别是同一个连接,从而不需要重新建立连接。
4. QUIC
灵活且可进化
因为QUIC
是完全加密的,如果需要改变它的一些协议规则,只要连接两端升级协议就能解读新协议规则,而连接的中间设施不需要也无法知道QUIC
发生了什么变化。
然后,QUIC
的包头信息不像TCP
那样是固定的,QUIC
的包头信息可变,并且QUIC
支持各种各样的帧类型。
QUIC
使用自定义TLS
扩展携带所谓的传输参数,让端可以对QUIC
连接做配置。
目前大部分QUIC
的实现都在系统的用户态,而不是内核态。这意味着更容易做实验和部署自己想要的变化和扩展。
本文转载自: 掘金