一:QUIC协议导入
QUIC是一个通用的传输层网络协议,最初由Google的Jim Roskind设计,2012年实现并部署,2013年随着实验范围的扩大而公开发布,并向IETF描述。虽然长期处于互联网草案阶段,但在从Chrome浏览器到Google服务器的所有连接中,超过一半的连接都使用了QUIC。Microsoft Edge、Firefox和Safari都支持它,但默认情况下没有启用。其于RFC9000中正式推出标准化版本。
在QUIC标准协议出来之前,各个厂家可以基于UDP开发自己版本的QUIC,国外的如Google的gquic_q023,gquic_q043,gquic_q046等QUIC版本,Facebook的mvfstQUIC版本,国内的如腾讯旗下的微信QUIC版本。基本上早期QUIC的定制玩家都是大厂,也只有大厂才有这样的业务定制需求。
2015年6月,QUIC规范的互联网草案提交给IETF进行标准化。2016年,成立了QUIC工作组。2018年10月,IETF的HTTP工作组和QUIC工作组共同决定将QUIC上的HTTP映射称为 "HTTP/3",以提前使其成为全球标准。2021年5月IETF公布RFC9000,QUIC规范推出了标准化版本。标准出来之前的QUIC版本并不会因此而消失,预计会有相当长的一段时间为共存,直至标准版本统一江湖。
二:QUIC协议简介
QUIC 的英文全称为:Quick UDP Internet Connections。从名字上看大概也能看出来主打一个快字,是一种基于UDP的全新的低延时互联网传输协议
基于TCP,UDP传输层的协议已经发展了多年,协议栈集成在操作系统中,已经是非常成熟的协议,谷歌为什么要另辟蹊径自己开发一种基于UDP的传输协议呢。QUIC解决了现存协议哪些短板,QUIC自身的优势又有哪些?
众所周知,HTTP统一江湖后,从最初的HTTP/0.9,经历了HTTP/1.x,HTTP/2到最新的HTTP/3这几个大的更新版本。在HTTP/3版本之前,HTTP都是基于TCP协议进行上层扩展和优化,而伴随着移动互联网的发展,网络交互场景越来越丰富并要求及时性,传统TCP固有的性能瓶颈和短板在某些场景下越来越不能满足需求,原因有以下几点:
1,必不可少的握手带来的时延消耗
TCP建立连接的三次握手,必然带来1个RTT(可以理解为网络延迟)的延时消耗。另外TLS加密协议,需要双方交换加密参数来进行加密,它需要2个RTT。所以HTTP2需要3个RTT的时间才能建立一个完整的传输链路。对于直播以及抖音刷小视频等需要首帧秒开场景,握手延迟太大
2,多路复用的队首阻塞
在HTTP1.0和HTTP1.1中,下个请求必须在前一个请求返回后才能发出,导致带宽无法被充分利用,后续请求被阻塞(HTTP 1.1 尝试使用流水线(Pipelining)技术,但先天 FIFO(先进先出)机制导致当前请求的执行依赖于上一个请求执行的完成,容易引起队头阻塞,并没有从根本上解决问题)。
HTTP2在之前版本的基础上,针对上面的场景进行了改量,提出了多路复用,HTTP2重新定义底层 http 语义映射,允许同一个连接上使用请求和响应双向数据流。同一域名只需占用一个 TCP 连接,通过数据流(Stream)以帧为基本协议单位,避免了因频繁创建连接产生的延迟,减少了内存消耗,提升了使用性能,并行请求,且慢的请求或先发送的请求不会阻塞其他请求的返回。
多路复用解决了HTTP1.1中pipelining的不足,但是多路复用必须要在网络条件良好不经常丢包的网络条件下才能发挥其最大优势。若其中一条流的中间某个报文丢失,后面其他流的数据都会被阻塞,直到丢失的流数据重传完成其他流才能被继续传输。即使接收端已经收到之后流的数据包,HTTP协议也不会通知应用层去处理。而对于 HTTP 1.1 来说,可以开启多个 TCP 连接,出现这种情况反到只会影响其中一个连接,剩余的 TCP 连接还可以正常传输数据。在网络不好的情况下,HTTP 2的表现反倒不如HTTP 1.1了。
3,TCP协议的更新滞后
TCP协议是集成在操作系统的内核内,这就带来了TCP协议的一些更新很难被快速推广。因为你总不能要求用户因为TCP新的协议特性去升级操作系统。QUIC在应用层之上基于UDP实现丢包恢复,拥塞控制,加解密,多路复用等功能,将TCP相比如UDP的优势功能放到应用层的实现里,既能优化握手延迟,同时又完全解决内核协议更新滞后问题。解决了推广的问题,那协议的生命力会更加有活力。
基于以上TCP的短板,QUIC进行了全方位的改进:
1,低时延连接
QUIC建连时间大约0~1 RTT,在两方面做了优化:
1)传输层使用了UDP,减少了1个RTT三次握手的延迟。
2)加密协议采用了TLS 协议的最新版本TLS 1.3,相对之前的TLS 1.1-1.2,TLS1.3允许客户端无需等待TLS握手完成就开始发送应用程序数据的操作,可以支持1 RTT和0RTT。
对于QUIC协议,客户端第一次建连的握手协商需1-RTT,而已建连的客户端重新建连可以使用之前协商好的缓存信息来恢复TLS连接,仅需0-RTT时间。因此QUIC建连时间大部分0-RTT、极少部分1-RTT,相比HTTPS的3-RTT的建连,具有极大的优势。
2,连接迁移
一条 TCP 连接是由四元组标识的(源 IP,源端口,目的 IP,目的端口)。什么叫连接迁移呢?就是当其中任何一个元素发生变化时,这条连接依然维持着,能够保持业务逻辑不中断。当然这里面主要关注的是客户端的变化,因为客户端不可控并且网络环境经常发生变化,而服务端的 IP 和端口一般都是固定的。比如下班了,在路上给异地恋的女友打电话走到家门前会自动连上家里的wifi这时候微信电话会有个短暂的中断,这是因为WIFI 和 4G/5G 移动网络切换时,客户端的 IP 会发生变化,需要重新建立和服务端的 TCP 连接。
QUIC支持连接迁移,它用一个(一般是64位随机数)ConnectionID标识连接,这样即使源的IP或端口发生变化,只要ConnectionID一致,连接都可以保持,不会发生切断重连
3,无队头阻塞
QUIC支持多路复用,相比HTTP/2,QUIC的流与流之间完全隔离的,互相没有时序依赖。如果某个流出现丢包,不会阻塞其他流数据的传输和应用层处理,所以这个方案并不会造成队首阻塞。
4,灵活的拥塞控制
QUIC 的传输控制不再依赖内核的拥塞控制算法,而是实现在应用层上,这意味着我们根据不同的业务场景,实现和配置不同的拥塞控制算法以及参数。用户可以插拔式选择像Cubic、BBR、Reno等拥塞控制算法,也可以根据具体的场景定制私有算法。
5,前向纠错(FEC)
QUIC支持前向纠错,弱网丢包环境下,动态的增加一些FEC数据包,可以减少重传次数,提升传输效率。