文|曾柯(花名:毅丝 )
蚂蚁团体高级工程师
负责蚂蚁团体的接入层建设工作
次要方向为高性能平安网络协议的设计及优化
本文 10279 字 浏览 18 分钟
PART. 1 引言
作为系列文章的第一篇,引言局部就先略微繁琐一点,让大家对这个系列文章有一些简略的认知。
先介绍下这个系列文章的诞生背景。QUIC、HTTP/3 等字眼想来对大家而言并不生疏。从集体的视角来看,大部分开发者其实都曾经有了一些背景常识,比方 HTTP/3 的外围是依赖 QUIC 来实现传输层及 TLS 层的能力。而谈及其中细节之时,大家却又知之甚少,相干的文章大多只是浅尝辄止的对一些 HTTP/3 中的机制和个性做了介绍,少有深刻的剖析,而对于这些机制背地诞生起因,设计思路的剖析,就更难得一见了。
从集体并不大量的 RFC 浏览及 draft 写作经验来看,和撰写论文文献一样,为了保障一份 RFC 的精简以及表述精确,当然也是为了编写过程的简略。在波及到其余相干协定时,作者往往是通过间接援用的形式来进行表述。这也就意味着间接通过浏览 RFC 来学习和理解网络协议是一个曲线绝对比拟平缓的过程,往往读者在浏览到一个要害局部的时候,就不得不跳转到其余文档,而后反复这个令人头痛的过程,而当读者再次回到原始文档时,可能都曾经忘了之前的上下文是什么。
而 HTTP/3,波及到 QUIC、TLS、HTTP/2、QPACK 等规范文档,而这些规范文档各自又有大量的关联文档,所以学习起来并不是一个容易的事。
当然,系列文章的立题为“深刻 HTTP/3”,而不是“深刻 QUIC”,其背地的起因就是 HTTP/3 并不仅仅只是 QUIC 这么一个点,其中还蕴含有大量现有 HTTP 协定和 QUIC 的有机联合。在系列文章的后续,也会对这一部分做大篇幅的深入分析。
一个协定的性能优良与否,除了自身的设计之外,也离不开大量的软硬件优化,架构落地,专项设计等工程实践经验,所以本系列除了会针对 HTTP/3 自身个性进行分享之外,也会针对 HTTP/3 在蚂蚁落地的计划进行分享。
引言的最初,也是本文的正式开始。
据统计,人类在学习新的常识时,比拟习惯从已有的常识去类比和推断,以产生更粗浅的理性和理性认识。我想对大部分同学而言,“TCP 为什么要三次握手以及四次挥手?”这个问题,颇有点经典的不能再经典的滋味,所以明天这篇文章也将从 QUIC 链接的建设流程及敞开流程动手,开始咱们系列的第一篇文章。
PART. 2 链接建设
2.1 重温 TCP
“TCP 为什么要三次握手?”
在答复问题之前咱们须要理解 TCP 的实质,TCP 协定被设计为一种面向连贯的、牢靠的、基于字节流的全双工传输层通信协议。
“牢靠”意味着应用 TCP 协定传输数据时,如果 TCP 协定返回发送胜利,那么数据肯定曾经胜利的传输到了对端,为了保证数据的“牢靠”传输,咱们首先须要一个应答机制来确认对端曾经收到了数据,而这就是咱们相熟的 ACK 机制。
“流式”则是一种应用上的形象(即收发端不必关注底层的传输,只需将数据当作继续一直的字节流去发送和读取就好了)。“流式”的应用形式强依赖于数据的有序传输,为了这种应用上的形象,咱们须要一个机制来保证数据的有序,TCP 协定栈的设计则是给每个发送的字节标示其对应的 seq(理论利用中 seq 是一个范畴,但其实在成果就是做到了每个字节都被有序标示),接收端通过检视以后收到数据的 seq,并与本身记录的对端以后 seq 进行比对,以此确认数据的程序。
“全双工”则意味着通信的一端的收发过程都是牢靠且流式的,并且收和发是两个齐全独立,互不烦扰的两个行为。
能够看到,TCP 的这些个性,都是以 seq 和 ACK 字段作为载体来实现的,而所有 TCP 的交互流程,都是在为了上述个性服务,当然三次握手也不例外,咱们再来看 TCP 的三次握手的示意图:
为了保障通信单方都能确认对端数据的发送程序,收发端都须要各自记录对端的以后 seq,并确认对端曾经同步了本人的 seq 才能够实现,为了保障这个过程,起码须要 3 个 RTT。而理论的实现为了效率思考,将 seq 和 ACK 放在了一个报文里,这也就造成了咱们熟知的三次握手。
当然,三次握手不仅仅是同步了 seq,还能够用来验证客户端是一个失常的客户端,比方 TCP 可能会面临这些问题:
(1)有一些 TCP 的攻打申请,只发 syn 申请,但不回数据,节约 socket 资源;
(2)已生效的连贯申请报文段忽然又传送到了服务端,这些数据不再会有后续的响应,如何避免这样的申请浪费资源?
而这些问题只是三次握手棘手解决的问题,不是专门为了它们设计的三次握手。
仔细的你,可能曾经发现了一个问题,如果咱们约定好 client 和 server 的 seq 都是从 0(或者某个大家都晓得的固定值)开始,是不是就能够不必同步 seq 了呢?这样仿佛也就不须要三次握手那么麻烦了?能够间接开始发送数据?
当然,协定的设计者必定也想过这个计划,至于为什么没这么实现,咱们在下一章来看看 TCP 面临什么样的问题。
2.2 TCP 面临的问题
2.2.1 seq 攻打
在上一节咱们提到,TCP 依赖 seq 和 ACK 来实现牢靠,流式以及全双工的传输模式,而理论过程中却须要通过三次握手来同步双端的 seq,如果咱们提前约定好通信单方初始 seq,其实是能够防止三次握手的,那么为什么没有这么做呢?答案是平安问题。
咱们晓得,TCP 的数据是没有通过任何平安爱护的,无论是其 header 还是 payload,对于一个攻击者而言,他能够在世界的任何角落,伪造一个非法 TCP 报文。
一个典型的例子就是攻击者能够伪造一个 reset 报文强制敞开一条 TCP 链接,而攻打胜利的要害则是 TCP 字段里的 seq 及 ACK 字段,只有报文中这两项位于接收者的滑动窗口内,该报文就是非法的,而 TCP 握手采纳随机 seq 的形式(不齐全随机,而是随着工夫流逝而线性增长,到了 2^32 止境再回滚)来晋升攻击者猜想 seq 的难度,以减少安全性。
为此,TCP 也不得不进行三次握手来同步各自的 seq。当然,这样的形式对于 off-path 的攻击者有肯定成果,对于 on-path 的攻击者是齐全有效的,一个 on-path 的攻击者依然能够随便 reset 链接,甚至伪造报文,篡改用户的数据。
所以,尽管 TCP 为了平安做出过一些致力,但因为其本质上只是一个传输协定,平安并不是其原生的考量,在以后的网络环境中,TCP 会遇到大量的平安问题。
2.2.2 不可避免的数据安全问题
置信 SSL/TLS/HTTPS 这一类的字眼大家都不生疏,整个 TLS(传输平安层)实际上解决的是 TCP 的 payload 平安问题,当然这也是最紧要的问题。
比方对一个用户而言,他可能能容忍一次转账失败,但他必定无奈容忍钱被转到攻击者手上去了。TLS 的呈现,为用户提供了一种机制来保障中间人无奈读取,篡改的 TCP 的 payload 数据,TLS 同时还提供了一套平安的身份认证体系,来避免攻击者假冒 Web 服务提供者。然而 TCP 的 header 这一层依然是不在爱护范畴内的,对于一个 on/off-path 攻击者,依然具备实践上随时敞开 TCP 链接的能力。
2.2.3 为了平安引发的效率问题
在以后的网络环境中,平安通信曾经成为了最根本的要求。相熟 TLS 的同学都晓得,TLS 也是须要握手和交互的,尽管 TLS 协定通过多年的实际和演进,曾经设计并落地了大量的优化伎俩(如 TLS1.3、会话复用、PSK、0-RTT 等技术),但因为 TLS 和 TCP 的分层设计,一个平安数据通道的建设实际上仍是一个绝对繁琐的流程。以一次基于 TLS1.3 协定的数据安全通道新建流程为例,其具体交互如下图:
能够看到,在一个 client 正式开始发送应用层数据之前,须要 3 个 RTT 的交互,这算是一个十分大的开销。而从流程上来看,TCP 握手和 TLS 的握手仿佛比拟类似,有交融在一起的可能。确实有相干的文献探讨过在 SYN 报文里交融 ClientHello 的可行性,不过因为以下起因,这部分的摸索也缓缓不了了之。
- TLS 自身也是基于有序传输设计的协定,交融在 TCP 中须要做大量的从新设计;
- 出于平安的思考,TCP 的 SYN 报文被设计为不能携带数据,如果要携带 clienthello,则须要对协定栈做大量改变,而因为 TCP 是一个内核协定栈,改变和迭代是一个苦楚且难以落地的过程;
- 新的协定难以和传统 TCP 兼容,大面积应用的可能性也很低。
2.2.4 TCP 的设计问题
出于 TCP 设计的历史背景,过后的网络状况并没有当初这么简单,整个网络的瓶颈在于带宽,所以整个 TCP 的字段设计十分精简,然而造成的成果就是将管制通道和数据通道被耦合的设计在了一起,在某些场景下就会造成问题。
比方:
seq 的二义性问题:构想这样的一个场景,发送端发送了一个 TCP 报文,因为通信的中间设备产生了阻塞,导致该报文被提早转发了,发送端迟迟未收到 ACK,便从新发送了一个 TCP 报文,在新的 TCP 报文达到接收端时,被提早转发的报文也达到了接收端,接收端只会响应一个 ACK。而客户端收到 ACK 时,并不分明这个 ACK 是对提早转发的报文的 ACK,还是新的报文的 ACK,带来的影响也就是 RTT 的预计会不精确,从而影响拥塞控制算法的行为,升高网络效率。
难用的 TCP keepalive:比方 TCP 连贯中的另一方因为停电忽然断网,咱们并不知道连贯断开,此时发送数据失败会进行重传,因为重传包的优先级要高于 keepalive 的数据包,因而 keepalive 的数据包无奈发送进来。只有在长时间的重传失败之后咱们能力判断此连贯断开了。
队头阻塞问题:严格来说这并不算 TCP 本身的问题,因为 TCP 自身是一个面向链接的协定,它保障了一个链接上的数据牢靠传输,也算实现了工作。然而随着互联网的遍及,人们利用网络传输的数据越来越多,如果将所有数据都放在一个 TCP 链接上传输,其中某一个数据产生丢包,前面的数据的传输都会被 block 住,重大影响效率。当然,应用多个 TCP 链接传输数据是一种解决方案,但多个链接又会带来新的开销问题及链接治理问题。
理解了 TCP 的这些问题,咱们就能从 QUIC 的一系列简单的机制中抽丝剥茧,看清 QUIC 自身设计的源头思路。
2.3 QUIC 的建联设计
和 TCP 一样,QUIC 的首要指标也是提供一个牢靠、有序的流式传输协定。不仅如此,QUIC 还要保障原生的数据安全以及传输的高效。
能够说,QUIC 就是在以一种更简洁高效的机制去对标 TCP+TLS。当然,和 TCP+TLS 一样,QUIC 建联流程的实质都是在为上述个性服务,因为 QUIC 是基于 UDP 从新设计的协定,便也就没那么多的历史包袱,咱们先来整顿下咱们对这个新的协定的诉求:
整顿好需要之后,咱们再来看看 QUIC 实现的成果。
先来看一个 QUIC 链接的建设流程,一次 QUIC 链接建设的粗略示意图如下:
能够看到,QUIC 相比于 TCP+TLS,只须要 1.5 个 RTT 就能实现建联,大大晋升了效率。相熟 TLS 的同学可能会发现 QUIC 的建联流程仿佛跟 TLS 握手没有太大区别,TLS 自身又是一个强依赖于数据有序牢靠传输的协定,然而 QUIC 又依赖 TLS 去达成有序且牢靠的能力,这仿佛成为了一个鸡和蛋的问题,那么 QUIC 是如何解决这个问题的呢?
咱们须要更深一步去看看 QUIC 建联的流程,粗略示意图仅仅只能帮咱们粗略感触下 QUIC 相比于 TCP+TLS 流程的高效,咱们来进一步看看更精细化的 QUIC 建联流程:
这里的图显得有些繁琐,抛去 TLS 握手的细节(对于 QUIC 的 TLS 设计,咱们会在系列文章的后续专门用一篇文章解说),整个流程实际上还是和 TCP 一样是一个申请 - 响应的模式,然而相比于 TCP+TLS,咱们还看到了一些不一样的中央:
1. 图中多了 ”init packet”、”handshake packet”、”short-header packet” 的概念;
2. 图中多了 pkt_number 的概念以及 stream+offset 的概念;
3.pkt_number 的下标变动仿佛有些奇怪。
而这些不同机制就是 QUIC 实现相比于 TCP 来说更高效的点,让咱们来逐个剖析。
2.3.1 pkt_number 的设计
pkt_number 从流程图看起来,和 TCP 的 seq 字段比拟相似,然而实际上还是有不少差异,能够说,pkt_number 的设计就是为了解决后面提到的 TCP 的问题的,咱们来看看 pkt_number 的设计:
- 从 0 开始的下标
后面咱们提到过,如果 TCP 的 seq 是一个从 0 开始的字段,那么其实不须要握手,就能够开始数据的有序发送,所以解决 TLS 和有序牢靠传输这个鸡和蛋问题的计划非常简单。即 pkt_number 从 0 开始计数,便可间接保障 TLS 数据的有序。
- 加密 pkt_number 以保障平安
当然 pkt_number 从 0 开始技术便也就遇上了和 TCP 一样的平安问题,解决方案也很简略,就是用为 pkt_number 加密,pkt_number 加密后,中间人便无奈获取到加密的 pkt_number 的 key,便也无奈获取到实在的 pkt_number,也就无奈通过观测 pkt_number 来预测后续的数据发送。而这里又引申出了另一个问题,TLS 须要握手实现后能力失去中间人无奈获取的 key,而 pkt_number 又在 TLS 握手之前又存在,这看起来又是一个鸡和蛋的问题,至于其解决方案,这里先卖一个关子,留到前面 QUIC-TLS 的专题文章再讲。
- 细粒度的 pkt_number space 的设计
TLS 严格来说并不是一个状态严格递进的协定,每进入一个新的状态,还是有可能会收到上一个状态的数据,这么说有点形象。
举个例子,TLS1.3 引入了一个 0-RTT 的技术,该技术容许 client 在通过 clientHello 发动 TLS 申请时,同时发送一些应用层数。咱们当然冀望这个应用层数据的过程绝对于握手过程来说是异步且互不烦扰的,而如果他们都是用同一个 pkt_number 来标示,那么应用层数据的丢包势必会导致对握手过程的影响。所以,QUIC 针对握手的状态设计了三种不同的 pkt_number space:
(1) init;
(2) Handshake;
(3) Application Data。
别离对应:
(1) TLS 握手中的明文数据传输,即图中的 init packet;
(2) TLS 中通过 traffic secret 加密的握手数据传输,即图中 handshake packet;
(3)握手实现后的应用层数据传输及 0-RTT 数据传输,即图中的 short header packet 以及图中暂未画出的 0-RTT packet。
三种不同的 space 保障了三个流程的丢包检测互不影响。对于这部分在系列文章后续 (对于 QUIC 丢包检测) 还会再次深刻分析。
- 永远自增的 pkt_number
这里的永远自增指的是 pkt_number 的明文随每个 QUIC packet 发送,都会自增 1。pkt_number 的自增解决的是二义性问题,接收端收到 pkt_number 对应的 ACK 之后,能够明确的晓得到底是重传的报文被 ACK 了,还是新的报文被 ACK 了,这样 RTT 的预计及丢包检测,就能够更加精密,不过仅仅只靠自增的 pkt_number 是无奈保证数据的有序的,咱们再来看看 QUIC 提供了什么样的机制保证数据的有序。
2.3.2 基于 stream 的有序传输
咱们晓得 QUIC 是基于 UDP 实现的协定,而 UDP 是不牢靠的面向报文的协定,这和 TCP 基于 IP 层的实现并没有什么实质上的不同,都是:
(1) 底层只负责尽力而为的,以 packet 为单位的传输;
(2) 下层协定实现更要害的个性,如牢靠,有序,平安等。
从后面咱们晓得 TCP 的设计导致了链接维度的队头阻塞问题,而仅仅依附 pkt_number 也无奈实现数据的有序,所以 QUIC 必须要一种更细粒度的机制来解决这些问题:
- 流既是一种形象,也是一种单位
TCP 队头阻塞的根因来自于其一条链接只有一个发送流,流上任意一个 packet 的阻塞都会导致其余数据的失败。当然解决方案也不简单,咱们只须要在一条 QUIC 链接上形象出多个流来即可,整体的思路如下图:
只有能保障各个 stream 的发送独立,那么咱们实际上就防止了 QUIC 链接自身的队头阻塞,即一个流阻塞咱们也能够在其余流上发送数据。
有了单链接多流的形象,咱们再来看 QUIC 的传输有序性设计,实际上 QUIC 在 stream 层面之上,还有更细粒度的单位,称作 frame。一个承载数据的 frame 携带有一个 offset 字段,表明本人绝对于初始数据的偏移量。而初始偏移量为 0,这个思路等价于 pkt_number 等于 0,即不须要握手即可开始数据的发送。相熟 HTTP/2、GRPC 的同学应该比较清楚这个 offset 字段的设计,和流式数据的传输是一样的。
- 一个 TLS 握手也是一个流
尽管 TLS 数据并没有一个固定的 stream 来标示,但其能够被看作为一个特定的 stream,或者说是所有其余 stream 能建设起来的初始 stream,因为它其实也是基于 offset 字段和固定的 frame 来承载的,这也就是 TLS 数据有序的保障所在。
- 基于 frame 的管制
有了 frame 这一层的形象之后,咱们当然能够做更多的事件。除了承载理论数据之外,也能够承载一些控制数据,QUIC 的设计吸取了 TCP 的经验教训,对于 keepalive、ACK、stream 的操作等行为,都设置了专门的管制 frame,这也就实现了数据和管制的齐全解耦,同时保障了基于 stream 的细粒度管制,让 QUIC 成为更精细化的传输层协定。
讲到这里,其实能够看到咱们从 QUIC 建联流程的探讨中,曾经明确了 QUIC 设计的指标,正如文章中始终在强调的概念:
“无论是建联还是什么流程,都是在为实现 QUIC 的个性而服务”。
咱们当初对 QUIC 的个性及实现曾经有了一些认知,来小结一下:
此时,咱们再来看看 QUIC 的建联过程中的一些设计,就不会再被其简单的流程所困扰,更能直击它的实质,因为这些设计是在 QUIC 建联大框架确认下来之后,一些细枝末节的点,而这些点往往又会在 RFC 中占据不小的篇幅,耗费读者的心力。
举个例子,比方针对 QUIC 的放大攻打及其解决形式:放大攻打的原理为,TLS 握手过程中 clientHello 数据很少。但 server 可能响应很多数据,这就可能造成放大攻打,比方 attacker A 发动大量 clientHello,但把本人的 src ip 批改为 client B,这样 attacker A 就成倍的放大了本人的流量,以攻打 client B,其解决方案也很简略,QUIC 要求每个 client 的首包都 padding 到肯定的长度,并且在服务端提供了 address validation 机制,同时在握手实现之前,限度服务端响应的数据大小。
RFC9000 中花了一章节来介绍这个机制,但其本质来说只是针对 QUIC 以后握手流程的问题的修补,而不是为了设计这个机制再去设计了握手流程。
PART. 3 链接敞开
从 TCP 看 QUIC 链接的优雅敞开
链接敞开是一个简略的诉求,能够简略梳理为两个指标:
1. 用户能够被动优雅敞开链接,并能告诉对方,开释资源。
2. 当通信一端无奈建设的链接时,有一个告诉对方的机制。
然而诉求很简略,TCP 的实现却很不简单,咱们来看看这个 TCP 链接敞开流程状态机的转移图:
这个流程看起来就够简单了,牵扯进去的问题就更不少,比方经典面试题:
“为什么须要 TIME_WAIT?”
“TIME_WAIT 的连接数过多须要怎么解决?”
“tcp_tw_reuse 和 tcp_tw_recycle 等内核参数的作用和区别?”
而这所有问题的根因都来源于 TCP 的链接和流的绑定,或者说是管制信令和数据通道的耦合。
咱们不禁要提出一个灵魂拷问“咱们须要的是全双工的数据传输模式,但咱们真的须要在链接维度做这个事件吗?”这么说仿佛有一些形象,还是以 TCP 的 TIME_WAIT 设计为例子来阐明,咱们来自底向上的看看 TCP 的问题:
再回到咱们的问题上,如果咱们将流和链接辨别开,在链接维度保障流的控制指令牢靠传输,链接自身实现一个简略的单工敞开过程,即通信一端被动敞开链接,则整个链接敞开,是否所有就简略起来了呢?
当然这就是 QUIC 的解法,有了这一层思路之后,咱们来整顿下 QUIC 链接敞开的诉求:
抛开流的敞开流程设计(对于流的这部分会在系列文章后续对于 stream 的设计进行分享),在链接维度咱们就能够失去一个清新的状态机:
能够看到,得益于单工的敞开模式,在整个 QUIC 链接敞开的流程里,敞开指令只有一个,即图中的 CONNECTION_CLOSE,而敞开的状态也只有两个,即图中的 closing 和 draing。咱们先来看看两种状态下终端的行为:
- closing 状态:当用户被动敞开链接时,即进入该状态,该状态下,终端收到所有的应用层数据都将只会回复 CONNECTION_CLOSE
- draining 状态:当终端收到 CONNECTION_CLOSE 时,即进入该状态,该状态下终端不再回复任何数据
更简略的是,CONNECTION_CLOSE 是一个不须要被 ACK 的指令,也就意味着不须要重传。因为从链接维度而言,咱们只须要保障最初能胜利敞开的链接,并且新的链接不被老的敞开指令影响即可,这种简略的 CONNECTION_CLOSE 指令就能实现所有的诉求。
3.2 更平安的 reset 的形式
当然,链接敞开也分为多种状况,和 TCP 一样,除了上一节提到的 QUIC 一端被动敞开链接的模式,QUIC 也须要提供无奈回复响应时的,间接 reset 对端链接的能力。
而 QUIC reset 对端链接的形式相比于 TCP 来说更加平安,该机制被称作 stateless reset,这并不是一个十分复杂的机制。在 QUIC 链接建设好之后,QUIC 单方会同步一个 token,而后续的链接敞开将通过校验这个 token 来来判断该对端是否有权限来 reset 这个链接,这种机制从根本上躲避了后面提到的 TCP 被歹意 reset 的这种攻打模式,整个流程如下图:
当然,stateless reset 的计划并不是银弹,平安的代价是更窄的应用范畴。因为为了保障平安,token 必须通过平安的数据通道进行传输(在 QUIC 中被限定为 NEW_TOKEN frame),并且接收端须要维持一个记录这个 token 的状态,也只有通过这个状态才能够保障 token 的有效性。
因而 stateless reset 被限定为 QUIC 链接敞开的最初伎俩,并且也只能在只能应用在客户端和服务端均处于一个绝对失常的状况下失常工作,比方这样的状况 stateless reset 就不实用,服务端并没有监听在 443 端口,但客户端发送数据到 443 端口,而这种状况在 TCP 协定栈下是能够 RST 掉的。
3.3 工程考量的超时断链
keepalive 机制自身并没有什么花色,都是一个计时器加探测报文即可搞定,而 QUIC 得益于链接和数据流的拆分,敞开链接变成了一个非常简单的事件,keepalive 也就变得更简略易用,QUIC 在链接维度上提供了名为 PING frame 的控制指令,用于被动探测保活。
更简略的是,QUIC 在超时后敞开链接的形式是 silently close,即不告诉对端,本机间接开释掉链接所有的资源。silently close 的益处是资源能够立刻失去开释,特地是对于 QUIC 这种单链接上既要保护 TLS 状态,也要保护流状态的协定来说,有很大的收益。
但其劣势在于后续如果有之前链接数据到来,则只能通过 stateless reset 的形式告诉对端敞开链接,stateless reset 的敞开相对来说 CONNECTION_CLOSE 开销更大。因而这部分能够说齐全是一个 tradeoff,而这部分的设计方案的最终敲定,更多来自于大量工程实际的教训与后果。
PART. 4 从 QUIC 链接的建设与敞开看协定的演进
从 TCP 到 QUIC,尽管只是网络协议技术的演进,但咱们也能够管中窥豹地看一下整个网络倒退的趋势。链接的建设与敞开只是咱们对 QUIC 协定的切入点,正如文章始终在强调的局部,无论是建联还是什么流程,都是在为实现 QUIC 的个性而服务,而本文除了在详细分析 QUIC 的链接建设的敞开流程之外,更是在总结这些个性的由来及设计思路。
通读全文,咱们能够看到,一个现代化的网络协议曾经绕不开平安这个诉求了,能够说“平安是所有的根底,效率则是永恒的谋求”。
而 QUIC 首先从收敛分层协定的思路登程,对立了平安和牢靠两种交互诉求,这仿佛也在提醒咱们,将来协定的倒退,仿佛也不用再齐全听从 OSI 的模型。分层是为了各个组件更良好分工协作,而收敛则是极致的性能谋求,TCP+TLS 能够收敛到 QUIC,那么就如华为提出的 NEW IP 技术一样,如果咱们把智能路由等技术联合起来,所有三层及以上网络协议也未尝不能收敛到一个全新的 IPSEC 协定中去。
当然这些都来的太远了,QUIC 自身是一个十分接地气的协定,在其以开源为主导的规范造成过程中,排汇了大量工程教训,使其不至于有太多理想化的个性,且可扩展性十分强,我想将来这样的工作模式,也将是一种支流的模式。
结 语
撰写本文是一个苦楚的过程,正如浏览 RFC 一样,想要将 QUIC 某个方向的技术齐全自蕴含在一篇文章之内简直不可能,而本文抉择将一些其余的依赖技术用弱化的形式来表白,并冀望能在未来以繁多文章的形式去着重介绍。
因而读者若想要全面了解 HTTP/3 或者 QUIC,也请关注后续的文章,并拉通浏览,方能有更深的领会。
当然,本文都是基于作者本人的集体了解,不免存在纰漏之处,如果读者发现有相干问题,欢送随时一起深入探讨。
本周举荐浏览
云原生运行时的下一个五年
积跬步至千里:QUIC 协定在蚂蚁团体落地之综述
网商双十一基于 ServiceMesh 技术的业务链路隔离技术及实际
Service Mesh 在中国工商银行的摸索与实际