技术素养:新一代基于UDP的低延迟网络传输层协议——Quic详细说明
时间:2020-10-20
1.写在前面
如果你的应用不需要任何修改,它可以提高15%以上的访问速度。特别是在网络薄弱的时候,接入速度可以提高20%以上。
如果你的应用经常在4G和WIFI网络之间切换,它就不会被断开,也不需要重新连接,用户也不会有任何感觉。如果您的应用程序同时需要TLS安全性和HTTP2多路复用。
如果您刚刚听说了HTTP2是下一代互联网协议,如果您刚刚注意到TLS1.3是一个革命性的里程碑式的协议,那么这两个协议已经受到了另一个新兴协议的影响和挑战。
如果这种新的协议正在出现,它的名字就叫“快”,并且它正在被标准化为新一代的互联网传输协议。
你愿意花一点时间来理解这个协议吗?你愿意致力于研究这个协议吗?你愿意推动企业使用这个协议吗?
建议:如果你觉得这篇文章有点难懂,你可以读一下《网络编程懒惰导论》(10):到了泡尿的时候了,赶快理解QUIC协议。
2.相关文章
网络编程中的懒人入门(10):泡在尿里的时候,快速理解quic协议
技术素养:新一代基于UDP的低延迟网络传输层协议
让互联网更快:分享腾讯新一代QUIC协议的技术实践
“七牛云技术共享:用QUIC协议实现实时视频直播0卡住了!》
3.这篇文章的作者
技术素养:基于UDP的新一代低延迟网络传输层协议——quic详细说明_ 6ca20203jw1e8qgp5bmzyj2050050aa8.jpg
罗成:腾讯R&D高级工程师。目前,他主要负责腾讯stgw(腾讯安全云网关)的相关工作,统筹推进腾讯内部、腾讯公共云和混合云的七层负载均衡以及全站HTTPS接入。对HTTPS、SPDY、HTTP2、QUIC等应用层协议、高性能服务器技术、云网络技术、用户访问速度、分布式文件传输等有深入的了解。(作者微博:点击此处进入)
4.QUIC协议概述
技术素养:新一代基于UDP的低延迟网络传输层协议——quic详细说明_ x1.jpg。
Quic的全称是快速udp互联网连接[1],“快速udp互联网连接”(与英语quick谐音,称为“quick”)是由谷歌提出的一种协议,它使用UDP进行多路传输和并发传输。
与广泛使用的http2+tcp+tls协议相比,Quic具有以下优势[2]:
减少了TCP三次握手和TLS的握手时间;
改善拥塞控制:
避免被队列头阻塞的多路复用;
连接迁移;
前向冗余纠错。
下图是网络层比较图:
技术素养:基于UDP-Quic的新一代低延迟网络传输层协议详细解释了_WX20180104-122733@2x.png
下图是通信延迟的比较图:
技术素养:新一代基于UDP的低延迟网络传输层协议
5.你为什么需要QUIC
5.1概述
自20世纪90年代互联网兴起以来,大多数互联网流量传输只使用少数网络协议。IPv4用于路由,TCP用于连接级流量控制,SSL/TLS协议用于传输安全,DNS用于域名解析,HTTP用于应用数据传输。
近三十年来,这些协议的发展非常缓慢。TCP主要是拥塞控制算法的改进,SSL/TLS基本保持不变,而几个小的改动主要是密码套件的升级。TLS1.3[3]是一个跨越式的变化,但迄今为止,它尚未正式发布。尽管IPv4已经取得了很大的进步,实现了IPv6并为DNS添加了一个安全的DNSSEC,但是部署进度和IPv6一样缓慢。
随着移动互联网的快速发展和物联网的逐渐兴起,网络交互的场景越来越丰富,网络传输的内容越来越庞大,用户对网络传输效率和网络响应速度有了更高的要求。
一方面,它是一个历史悠久、用途广泛的古老礼仪;另一方面,用户的使用场景要求越来越高的传输性能。
下列长期存在的问题和矛盾越来越突出:
协议的长期历史导致了中间设备的刚性;
依赖于操作系统的实现导致协议本身的刚性;
建立连接的握手延迟大;
组长被封锁了。
这是一个分章节的简要解释。
5.2中间设备的刚度
这可能是因为TCP使用时间太长,而且非常可靠。因此,我们的许多中间设备,包括防火墙、NAT网关、整流器等等,都有一些常规操作。
例如,一些防火墙只允许访问80和443端口,而不允许访问其他端口。NAT网关在转换网络地址时会重写传输层的报头,这可能会导致双方都无法使用新的传输格式。出于安全原因,整流器和中间代理有时会删除一些未知的选项字段。
TCP协议最初支持端口、选项和功能的添加和修改。然而,由于TCP协议和众所周知的端口和选项已经被使用了很长时间,中间设备已经依赖于这些隐藏的规则,所以这些内容的修改很容易被中间链路干扰并失败。
这些干扰也导致对TCP协议的大量优化变得谨慎和困难。
5.3根据操作系统的实现,协议变得僵化
TCP是由操作系统在内核西部堆栈层实现的,它只能由应用程序使用,不能直接修改。尽管应用程序的更新迭代非常快速简单。然而,TCP的迭代非常慢,因为升级操作系统很麻烦。
如今,移动终端越来越受欢迎,但一些移动用户的操作系统升级可能仍会滞后几年。个人电脑方面的系统升级严重滞后,尽管windows xp已经存在了近20年,但仍被大量用户使用。
服务器系统不依赖于用户升级,但是因为操作系统升级涉及到更新底层软件和运行时,所以它也是保守和缓慢的。
这意味着即使TCP有更好的特性更新,也很难快速推广。例如,TCP快速打开。尽管它是在2013年提出的,但许多版本的Windows仍然不支持它。
5.4建立连接的握手延迟很大
无论是HTTP1.0/1.1、HTTPS还是HTTP2,TCP都是用于传输的。HTTPS和HTTP2也需要TLS协议来实现安全传输。
这导致两次握手延迟:
1)TCP三次握手造成的TCP连接建立延迟;
2)TLS完整握手至少需要建立2个RTT,简化握手需要1个RTT握手延迟。
对于许多短连接情况,这种握手延迟影响很大,无法消除。
5.5组长受阻
队列头阻塞主要是由TCP协议的可靠性机制引入的。TCP使用序列号来识别数据的顺序,数据必须按顺序处理。如果先前的数据丢失,即使后续数据到达,也不会通知应用层进行处理。
此外,在TLS协议级有一个队列头块,因为TLS协议根据记录处理数据,如果记录中的数据丢失,整个记录就不能被正确处理。
总的来说,TCP和TLS1.2之前的协议存在结构性问题。如果我们继续在现有的TCP和TLS协议的基础上实现一个全新的应用层协议,它将依赖于操作系统、中间件和用户的支持。部署成本非常高,阻力非常大。
因此,QUIC协议选择了UDP,因为UDP本身没有连接的概念,不需要三次握手,这优化了连接建立的握手延迟。同时,在应用层实现了TCP的可靠性、TLS的安全性和HTTP2的并发性,只需要客户端和服务器端的应用程序来支持QUIC协议,完全避免了操作系统和中间设备的限制。
6.QUIC核心功能
6.1连接建立延迟低
与HTTP2相比,0RTT连接可以说是QUIC最大的性能优势。那么什么是0RTT公司?
这有两个意思:
传输层可以建立连接;
加密层0RTT可以建立加密连接。
技术素养:新一代基于UDP的低延迟网络传输层协议
▲图1 HTTPS和QUIC的连接过程
例如,上图左侧是HTTPS完整的握手建立过程,需要3个即时通信终端。即使会话恢复[14]也需要至少2个RTT。
QUIC呢?由于它基于UDP协议,同时实现了0RTT的安全握手,所以在大多数情况下,只需要0RTT就可以实现数据传输。基于前向加密[15],0 RTT的成功率远高于TLS地震票证[13]。
6.2改善拥塞控制
TCP拥塞控制实际上包括四种算法:慢启动、拥塞避免、快速重传和快速恢复[22]。
默认情况下,QUIC协议目前使用的是三次拥塞控制算法,并且还支持三次字节、雷诺、雷诺字节、BBR、PCC等拥塞控制算法。
从拥塞算法本身来看,QUIC只是根据TCP协议重新实现的,那么QUIC协议的改进在哪些方面呢?主要有以下几点。
[可插拔]:
什么是可插拔的?就是能够非常灵活地生效、改变和停止。体现在以下几个方面:
1)不同的拥塞控制算法可以在应用层实现,无需操作系统或内核支持。这是一个飞跃,因为传统的TCP拥塞控制必须得到端到端网络协议栈的支持才能达到控制效果。但是,内核和操作系统的部署成本很高,升级周期很长,显然不能满足当今产品快速迭代和网络爆炸式增长的需求;
2)即使单个应用程序的不同连接也可以支持配置不同的拥塞控制。即使它是一个服务器,连接到它的用户的网络环境也有很大的不同。结合大数据和人工智能处理,我们可以为每个用户提供不同但更准确和有效的拥塞控制。例如,BBR是合适的,立方是合适的;
3)应用程序可以在不停止或升级的情况下改变拥塞控制。我们只需要修改配置并在服务器端重新加载它,并且我们可以在根本不停止服务的情况下切换拥塞控制。
STGW在配置级别进行了优化。我们可以对不同的服务、不同的网络标准甚至不同的RTT使用不同的拥塞控制算法。
[单调递增的包号]:
为了保证可靠性,TCP使用基于字节数的序列号和确认来确认消息的有序到达。
QUIC也是一个可靠的协议,它使用包号代替Tcp序列号,并且每个包号都严格增加,也就是说,即使包N丢失,重传包N的包号也不是N,而是大于N的值。对于TCP,重传段的序列号和原始段的序列号保持不变。正是由于这一特点,引入了TCP重传的模糊性。
技术素养:新一代基于UDP的低延迟网络传输层协议
▲图2传输控制协议重传的模糊性
如上图所示,在超时事件RTO发生后,客户端发起重传,然后接收Ack数据。由于序列号相同,这个Ack数据是对原始请求的响应还是对重传请求的响应?很难判断。
如果它被计为原始请求的响应,但实际上它是重传请求的响应(上图中的左边),采样RTT将变得更大。如果将其算作重传请求的响应,但实际上是原始请求的响应,很容易导致采样RTT值过小。
由于快速重传包和原始包的包数严格增加,这个问题很容易解决。
技术素养:新一代基于UDP的低延迟网络传输层协议
▲图3快速重传没有歧义
如上图所示,在实时操作发生后,可以根据重传的包号来确定准确的RTT计算。如果ack的包号为N+M,则根据重传请求计算采样RTT。如果确认的帕克塞数为n,则根据最初请求的时间计算采样RTT,并且没有歧义。
然而,仅仅通过严格增加包号来保证数据的顺序和可靠性是绝对不可能的。QUIC引入了流偏移的概念。
也就是说,一个流可以通过多个分组来传输,并且分组号被严格地增加而没有依赖性。但是如果包中的有效载荷是流,它需要依赖流的偏移量来保证应用数据的顺序。比如错误!找不到参考源。如图所示,发送方先后发送了数据包n和数据包n+1,流的偏移量分别为x和x+y。
假设分组N丢失,重传开始,重传的分组号是N+2,但是其流的偏移量仍然是x,所以即使分组N+2迟了,流x和流x+y仍然可以按顺序组织,并移交给应用程序进行处理。
技术素养:新一代基于UDP的低延迟网络传输层协议
▲图4流偏移保证订单
[不允许反悔]:
什么是食言?也就是说,接收者丢弃已经接收并报告给SACK选项[8]的内容。TCP协议不鼓励这种行为,但在协议级别上是允许的。主要考虑服务器资源有限,如缓冲区溢出、内存不足等。
反悔会对数据重传造成很大的干扰。因为Sack已经表示它已经被接收,但是接收者实际上丢弃了数据。
QUIC禁止在协议级别进行更新,一旦数据包被确认,就认为它必须被正确接收,从而减少了这种干扰。
[更多Ack块]:
TCP的Sack选项可以告诉发送方接收到的连续段的范围,方便发送方进行选择性重传。
TCP选项的最大长度只有40字节,因为Tcp报头的最大长度只有60字节,而标准报头占用20字节。此外,Tcp时间戳选项占用10个字节,因此只有30个字节保留给Sack选项。
每个Sack块的长度是8,加上Sack选项的头2字节,这意味着Tcp Sack选项最多只能提供3个块。
然而,快速确认帧可以同时提供256个确认块。在丢包率较高的网络中,增加Sack块可以提高网络的恢复速度,减少重传量。
[确认延迟时间]:
Tcp的时间戳选项[25]有一个问题,它只回显发送者的时间戳,但不计算从接收数据段到向接收者发送Ack的时间。这个时间可以简称为确认延迟。
这将导致RTT计算错误。下图:
技术素养:新一代基于UDP的低延迟网络传输层协议
可以认为,RTT计算的传输控制协议:
技术素养:新一代基于UDP的低延迟网络传输层协议
Quic计算如下:
技术素养:新一代基于UDP的低延迟网络传输层协议
当然,RTT的具体计算并不简单,所以需要抽样,并参照历史价值进行平滑计算。参考以下公式[9]:
技术素养:新一代基于UDP的低延迟网络传输层协议
6.3基于流和连接级别的流量控制
QUIC [22]的流控制类似于HTTP2,也就是说,它在连接和流级别提供两种流控制。为什么需要两种流量控制?主要是因为QUIC支持多路复用。
流可以被视为一个HTTP请求。
连接可以与TCP连接相比较。多路复用意味着一个连接上有多个流。有必要控制单个流和所有流作为一个整体。
QUIC实现流量控制的原理很简单:
告诉对方它可以通过window_update帧接收的字节数,这样发送方就不会发送超过这个数目的数据。
通过块帧告诉另一端,由于流量控制被阻止,数据无法发送。
QUIC的流量控制与TCP有些不同。为了确保TCP的可靠性,窗口左边缘向右滑动的长度取决于确认的字节数。如果数据包在中间丢失,即使收到序列号更大的数据段,该窗口也不能超过该序列号。
然而,QUIC是不同的。即使以前没有接收到某些数据包,它的滑动也只取决于接收到的最大偏移字节数。
技术素养:新一代基于UDP的低延迟网络传输层协议
▲图5快速流量控制
对于流:
技术素养:新一代基于UDP的低延迟网络传输层协议
对于连接:
技术素养:新一代基于UDP的低延迟网络传输层协议
同样,STGW在连接和流级别设置了不同的窗口。
最重要的是,当内存不足或上游处理性能出现问题时,我们可以通过流量控制来限制传输速率,以确保服务的可用性。
6.4无队列头阻塞的多路复用
QUIC的多路复用类似于HTTP2。多个HTTP请求(流)可以在一个QUIC连接上并发发送。然而,QUIC的多路复用比HTTP2有很大的优势。
QUIC,一个连接上多个流之间没有依赖性。这样,如果stream2丢失了一个udp数据包,它只会影响stream2的处理。它不影响流2前后的流处理。
这在很大程度上减轻甚至消除了团队头阻塞的影响。
多路复用是HTTP2 [7]最强大的功能,它可以在一个TCP连接上同时发送多个请求。但它也加剧了TCP的问题,队列头阻塞[11],如下图所示:
技术素养:新一代基于UDP的低延迟网络传输层协议
▲图6 HTTP2团队负责人阻塞
HTTP2在一个TCP连接上同时发送四个流。其中Stream1已经正确到达并被应用层读取。然而,流2的第三个tcp段丢失了。为了确保数据的可靠性,TCP需要发送方重新发送第三个数据段,以通知应用层读取下一个数据。虽然此时流3和流4的所有数据都已到达接收器,但它们被阻止。
不仅如此,因为HTTP2强制TLS,所以在TLS协议级别有一个队列头块[12]。
技术素养:新一代基于UDP的低延迟网络传输层协议
▲图7张力腿系统团队负责人阻塞
记录是TLS协议处理的最小单位,最大大小不能超过16K。一些服务器的默认大小是16K,例如Nginx。因为记录只能在数据一致性检查后进行加密和解密,所以即使16K记录丢失一个字节,也无法处理接收到的15.99K数据,因为它是不完整的。
那么为什么QUIC复用可以避免上述问题呢?
1)QUIC最基本的传输单元是数据包,它不会超过MTU的大小。整个加密和身份验证过程基于数据包,不会跨越多个数据包。这样,可以避免TLS协议的队列头阻塞;
2)流彼此独立。例如,如果流2丢失一个数据包,它将不会影响流3和流4。没有TCP队列头阻塞。
技术素养:新一代基于UDP的低延迟网络传输层协议
▲图8在QUIC复用期间没有队列头阻塞的问题
当然,不是所有的QUIC数据都不会受到队列头阻塞的影响。例如,QUIC目前使用Hpack压缩算法[10]。由于算法的限制,当头数据丢失时,可能会遇到队列头阻塞。
一般来说,当传输大量数据(如视频)时,QUIC几乎不受队列头阻塞的影响。
6.5加密和认证的消息
TCP协议报头未经加密和认证,因此在传输过程中很容易被中间网络设备篡改、注入和窃听。例如修改序列号和滑动窗口。这些行为可能是由于性能优化,也可能是主动攻击。
但是QUIC的包裹武装到了牙齿。除了单独的消息,如PUBLIC_RESET和CHLO,所有消息头都经过身份验证,消息体也经过加密。
这样,只要QUIC消息被修改,接收者就能及时发现,有效降低了安全风险。
如下图所示,红色部分是带身份验证的流帧的消息头。绿色部分是消息内容,全部加密。
技术素养:新一代基于UDP的低延迟网络传输层协议
6.6连接迁移
一个TCP连接[17]由四个部分(源IP、源端口、目的IP、目的端口)标识。什么是连接迁移?也就是说,当任何一个元素改变时,这个连接仍然保持,这可以保持业务逻辑不中断。当然,这里主要关心的是客户端的变化,因为客户端是不可控的,网络环境经常变化,而服务器的IP和端口通常是固定的。
例如,当您使用手机在WIFI和4G移动网络之间切换时,客户端的IP肯定会发生变化,因此您需要重新建立与服务器的TCP连接。
例如,当人们使用公共网络地址转换出口时,一些连接需要在竞争时重新绑定端口,这导致客户端的端口发生变化,并且还需要重新建立TCP连接。
针对TCP连接的变化,MPTCP[5]实际上有一个解决方案,但是因为MPTCP需要操作系统和网络协议栈的支持,部署阻力很大,目前还不适用。
因此,从TCP连接的角度来看,这个问题是无法解决的。
那么QUIC如何进行连接迁移呢?很简单,任何QUIC连接不再由IP和端口四元组来标识,而是由64位随机数来标识,因此即使IP或端口发生变化,只要ID保持不变,该连接仍将保持,并且上层业务逻辑将不会意识到该变化,也不会被中断,因此不需要重新连接。
因为该标识是由客户端随机生成的,长度为64位,所以冲突概率非常低。
6.7其他亮点
此外,QUIC还可以实现前向冗余纠错,当握手消息等重要数据包丢失时,可以根据冗余信息恢复握手消息。
QUIC还可以实现证书压缩,减少证书传输量,验证数据包报头。