QUIC(Quick UDP Internet Connection)协议概述

目录

1 前言

2 什么是QUIC

2.1 HTTP/1.0

2.2 HTTP/1.1

2.3 HTTP/2

2.4 TCP协议的阻塞问题

3 QUIC的协议栈

4 QUIC的报文结构

5 QUIC的核心技术

5.1 修改难度小

5.2 与TLS(Transport Layer Security)集成

5.3 建立连接低时延

5.4 连接迁移

5.5 多流复用,缓解队头阻塞

5.6 改进的拥塞控制机制

5.6.1 可插拔

5.6.2 单调递增的Packet Number

5.6.3 ACK Delay

5.6.4 不允许Reneging

5.6.5 更多ACK块

5.7 双层流量控制

5.7.1 stream级别

5.7.2 connection级别

6 QUIC的缺点


1 前言

作者在实习期间简单学习过QUIC协议的基本原理,也在GitHub上找过各类QUIC实现版本,具体的QUIC协议实现涉及到数据包、连接等多个状态机,想要深入研究的小伙伴可以去找些代码看。本篇仅做粗浅的简介。

2 什么是QUIC

QUIC(Quick UDP Internet Connection)是一种传输层协议,与TCP和UDP协议同运行在传输层。

QUIC协议起源于HTTP协议的需求。

2.1 HTTP/1.0

HTTP/1.0中,客户端(Client)想要发送多个请求(Request)时,当前请求必须上一个请求对应的、来自服务器(Server)的响应(Response)到达之后才能发送。这样会导致完成多个任务的时间很长。

图1 HTTP/1.0

2.2 HTTP/1.1

因此,在HTTP/1.1中,提出了所谓的客户端可以管道化(pipelining)并行发送多个请求。

但是对于服务器而言,还是必须得将上一个响应发送完后,才能发送下一个响应,即在服务器端并没有实现“管道”发送。

图2 HTTP/1.1

2.3 HTTP/2

之后,在HTTP/2中,则实现了基于应用层(即HTTP协议)的“多流复用”,以缩小多个任务场景下的完成时间。

图3 HTTP/2

HTTP/2中,客户端和服务器将数据进行“分帧”,将不同资源请求通过消息中的“stream ID”来区分,即哪个响应对应哪个请求,以及可以区分同时到达的多个请求/响应。

这样,在应用层层面就解决了队头阻塞的问题,但是HTTP协议是基于TCP的,而TCP协议本身存在固有的阻塞问题。

2.4 TCP协议的阻塞问题

TCP协议是一种基于字节流传输数据的协议,无法区分上层业务逻辑的区别,对于来自多个应用程序的数据流,都通过同一个TCP滑动窗口来维护传输。

图4 TCP的阻塞

如图所示,如果对来自应用程序1(stream ID 为1)的数据Seq3的确认ACK丢失后,客户端的滑动窗口会不滑动,直至超时重传Seq3,而这也会导致来自应用程序2(stream ID 为2)和应用程序3(stream ID 为3)的数据传输都堵塞。

这就是TCP协议固有的队头阻塞问题。而UDP协议不需要维护连接和滑动窗口等,在这方面有很大的可拓展性。因此,在HTTP/3中提出了配合应用协议的传输层协议QUIC,即HTTP/3是基于QUIC传输层协议去传输数据的。

而现在,QUIC协议作为一个独立的传输层协议,可作为接口服务于各类应用协议(不仅限于HTTP)。这就是QUIC协议的来源。

3 QUIC的协议栈

QUIC协议在TCP/IP协议栈所处的位置如下图,位于应用层和UDP层之间。

图5 QUIC协议栈

QUIC协议使用UDP协议,在此基础上模拟了TCP的三大功能:差错重传、拥塞控制、流量控制。

为什么明明是弥补TCP的缺陷,却还要模拟TCP的功能呢?

这是因为虽然TCP具有队头阻塞这样的问题,但是它和UDP协议比起来,通过差错重传和拥控流控机制,保证了数据传输的准确性和网络通信性能。这也是QUIC协议希望做到的。(取其精华去其糟粕)

同时,可以从图中看到,QUIC协议将原本应用层的“多流复用”功能在传输层实现了,即应用层不需要对不同请求进行特殊分流处理,扔给QUIC去做就行。

其次,QUIC集成了TLS1.3模块的加密功能,它也需要在数据传输前提前建立连接(和TCP类似),这部分是由TLS的握手(handshake)模块实现的。

4 QUIC的报文结构

QUIC协议基于UDP实现,因此一个QUIC报文(QUIC Packet)是作为一个UDP数据报(datagram)的负载(payload)部分,加上UDP数据报的头部(header)就组成一个UDP报文。

QUIC报文的具体结构如下图:

图6 QUIC报文

首先数据传输的管道是一个连接(Connection),如黄色框框,表示一个QUIC连接管道,进行数据传输。

第一级报文是UDP报文,QUIC packet作为UDP数据报的负载,如红色框框。

第二级报文是QUIC报文,包括头部(橘色框框)和负载(蓝色框框)。

第三级是帧结构(frame),如紫色框框,每个帧可以来自不同的应用程序,通过帧结构中的stream ID区分,对于来自同一个应用程序的数据,通过offset字段保证该数据在整个数据中的额有序位置。

5 QUIC的核心技术

5.1 修改难度小

(1)对TCP协议进行修改:TCP协议是在内核态实现,而操作系统的升级迭代太慢。

(2)通过QUIC协议来实现:QUIC协议在用户态实现,可以通过用户进行编程实现,容易修改。

5.2 与TLS(Transport Layer Security)集成

如图5所示,TCP与TLS是串行关系,通过调用TLS模块来对应用数据进行加密。

QUIC协议与TLS协议是相互集成的关系,QUIC协议使用TLS的Handshake模块进行建立连接,TLS使用QUIC的可靠性、有序交付作为记录层(Record模块)。

5.3 建立连接低时延

TLS和QUIC协议都存在两种建立连接的场景,一种是首次建连,一种是后续建连,如下图所示。

图7 TCP和QUIC建立连接

可以看到,TLS1.2和TLS1.3建立连接相差了一个RTT(Round-Trip Time, RTT),这时因为TLS1.2采用RSA秘钥交换算法,在第2个RTT时交换秘钥,而TLS1.3采用ECDHE密钥交换算法,在第1个RTT时交换秘钥。

TLS1.2的秘钥交换过程如下图所示:

图8 RSA秘钥交换过程

TLS1.3的秘钥交换过程如下图所示:

图9 ECDHE秘钥交换过程

以上都是作者个人理解,简单草图,有错误之处还请指正

5.4 连接迁移

(1)TCP协议:通过<源IP地址,源端口号,目的IP地址,目的端口号>标识,若客户端所在4G网络转到WiFi网络,客户端IP地址发生变化,TCP需要重新建立连接

(2)QUIC协议:通过一个随机生成的64位的connection ID(CID)标识连接,只要CID不变,连接就不断开

5.5 多流复用,缓解队头阻塞

QUIC基于UDP,UDP本身无队头阻塞(没有流量控制和确认机制)

QUIC对每个stream,维护各自的滑动窗口,一个QUIC packet丢失并不影响其他stream的窗口滑动。

图10 QUIC多流复用

举例:

Packet N丢失:stream 2阻塞,stream1、3正常; 

Packet N+2丢失:stream1、3阻塞,stream 2正常; 

思考:

①QUIC的多流复用能够提高并发流的性能,但并发流常见吗?

②121212对资源加载性能不一定最优(11112222对于业务1来说是最优的)。

③对被阻塞的资源,虽然有些浏览器可以开始编译/解析部分资源,但仍需等待完整资源到达后才能使用。

④对同一个Packet,最好别同时封装多个stream。

5.6 改进的拥塞控制机制

5.6.1 可插拔

(1)应用层面实现不同的拥塞控制算法;

(2)单个应用程序的不同连接支持不同的拥塞控制;

(3)应用程序不许停机和升级就能实现拥塞控制的变更;

(4)针对不同业务,不同网络制式,不同RTT,使用不同的拥塞控制算法。

5.6.2 单调递增的Packet Number

(1)TCP协议:原始Segment的序列号(Sequence Number,SN)与重传Segment相同。

图11 TCP重传/延迟到达

需判断ACK N+1是对原始还是重传的响应。

重传:如果判断为原始,则RTT偏大;

延迟:如果判断为重传,则RTT偏小;

(2)QUIC协议:QUIC packet number单调递增。

图12 QUIC重传/延迟到达

对于QUIC协议,客户端能区分对原始还是重传的ACK,可以精确估计RTT。

5.6.3 ACK Delay

(1)TCP:只回显发送方发送的时间戳。

(2)QUIC:能计算ACK Delay,使RTT估计更精确。

图13 ACK Delay

5.6.4 不允许Reneging

(1)Reneging:是指接收方丢弃已接收且上报给SACK选项的内容。

(2)TCP:协议层面允许Reneging(服务器资源有限)。Reneging会对重传造成干扰,SACK表明已收到,但实际接收方丢弃了该数据。

5.6.5 更多ACK块

(1)TCP协议:头部header最大有60字节,标准头部20个字节,option有40字节。其中,TCP timestamp option 10字节留给SACK的只有30字节;每个SACK Block有8字节,SACK头部占2字节,则最多3个SACK Block。

(2)QUIC协议:ACK frame最多可提供256个SACK Block。

5.7 双层流量控制

5.7.1 stream级别

限制单个stream可发送的数据量,防止单个stream消耗connection的全部缓冲区(通过流量控制frame通知发送方)。

5.7.2 connection级别

限制一个connection里所有stream加起来发送的字节数,防止发送方超过connection的缓冲容量。

6 QUIC的缺点

(1)根据Google的仿真数据和论文,可以看到,在网络质量好的网络中,如高带宽、低时延、低丢包率的场景,QUIC协议的性能不一定比TCP好。

(2)QUIC协议的CPU消耗是TCP/TLS的两倍左右。可能原因有:

  • QUIC是基于UDP协议进行设计开发的,而UDP在批量收发包的接口性能方面不如TCP;
  • QUIC需要对报文进行加解密,强制使用TLS模块;而TCP可选择使用TLS对数据进行安全加密,也可不使用。
  • ACK处理。TCP的ACK报文直接在内核通过tcp_ack函数进行处理;而QUIC先将所有报文放到用户态,再处理,导致了额外的用户级与内核级的切换,和数据从内核转移到用户的拷贝开销。

综上,可以看到QUIC协议并不是一类适用于所有通信场景下的协议,它在存在多并发流的场景下可以发挥良好的通信性能,缓解TCP的队头阻塞,提高数据包传输的时延。因此,需要因地制宜,用在合适的场景下,才能发挥QUIC协议性能。

  • 26
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值