互联网协议简介

113 阅读30分钟

本来想写一个阅读笔记的,奈何阮一峰大佬写的实在太好了,还是不要班门弄斧去乱改了,直接摘抄对以后得阅读可能更好。

互联网分层模型

五层模型

互联网的实现,分成好几层。每一层都有自己的功能,就像建筑物一样,每一层都靠下一层支持。

用户接触到的,只是最上面的一层,根本没有感觉到下面的层。要理解互联网,必须从最下层开始,自下而上理解每一层的功能。

如何分层有不同的模型,有的模型分七层,有的分四层。我觉得,把互联网分成五层,比较容易解释。

如上图所示,最底下的一层叫做"实体层"(Physical Layer),最上面的一层叫做"应用层"(Application Layer),中间的三层分别是"链接层"(Link Layer)、"网络层"(Network Layer)和"传输层"(Transport Layer)。越下面的层,越靠近硬件;越上面的层,越靠近用户。

层与协议

每一层都是为了完成一种功能。为了实现这些功能,就需要大家都遵守共同的规则。

大家都遵守的规则,就叫做"协议"(protocol)。

互联网的每一层,都定义了很多协议。这些协议的总称,就叫做"互联网协议"(Internet Protocol Suite)。它们是互联网的核心,下面介绍每一层的主要协议。

五层模型

实体层

我们从最底下的一层开始。

电脑要组网,第一件事要干什么?当然是先把电脑连起来,可以用光缆、电缆、双绞线、无线电波等方式。

这就叫做"实体层",它就是把电脑连接起来的物理手段。它主要规定了网络的一些电气特性,作用是负责传送 0 和 1 的电信号。

链路层

单纯的 0 和 1 没有任何意义,必须规定解读方式:多少个电信号算一组?每个信号位有何意义?

这就是"链接层"的功能,它在"实体层"的上方,确定了 0 和 1 的分组方式。

早期的时候,每家公司都有自己的电信号分组方式。逐渐地,一种叫做"以太网"(Ethernet)的协议,占据了主导地位。

以太网协议

以太网规定,一组电信号构成一个数据包,叫做"帧"(Frame)。每一帧分成两个部分:标头(Head)和数据(Data)。

组网

"标头"包含数据包的一些说明项,比如发送者、接收者、数据类型等等;"数据"则是数据包的具体内容。

"标头"的长度,固定为 18 字节。"数据"的长度,最短为 46 字节,最长为 1500 字节。因此,整个"帧"最短为 64 字节,最长为 1518 字节。如果数据很长,就必须分割成多个帧进行发送。

Mac 地址

上面提到,以太网数据包的"标头",包含了发送者和接收者的信息。那么,发送者和接收者是如何标识呢?

以太网规定,连入网络的所有设备,都必须具有"网卡"接口。数据包必须是从一块网卡,传送到另一块网卡。网卡的地址,就是数据包的发送地址和接收地址,这叫做 MAC 地址。

网卡

每块网卡出厂的时候,都有一个全世界独一无二的 MAC 地址,长度是 48 个二进制位,通常用 12 个十六进制数表示。

MAC地址

前 6 个十六进制数是厂商编号,后 6 个是该厂商的网卡流水号。有了 MAC 地址,就可以定位网卡和数据包的路径了。

广播

定义地址只是第一步,后面还有更多的步骤。

首先,一块网卡怎么会知道另一块网卡的 MAC 地址?

回答是有一种 ARP 协议,可以解决这个问题。这个留到后面介绍,这里只需要知道,以太网数据包必须知道接收方的 MAC 地址,然后才能发送。

其次,就算有了 MAC 地址,系统怎样才能把数据包准确送到接收方?

回答是以太网采用了一种很"原始"的方式,它不是把数据包准确送到接收方,而是向本网络内所有计算机发送,让每台计算机自己判断,是否为接收方。

上图中,1 号计算机向 2 号计算机发送一个数据包,同一个子网络的 3 号、4 号、5 号计算机都会收到这个包。它们读取这个包的"标头",找到接收方的 MAC 地址,然后与自身的 MAC 地址相比较,如果两者相同,就接受这个包,做进一步处理,否则就丢弃这个包。这种发送方式就叫做"广播"(broadcasting)。

有了数据包的定义、网卡的 MAC 地址、广播的发送方式,"链接层"就可以在多台计算机之间传送数据了。

网络层

网络层的由来

以太网协议,依靠 MAC 地址发送数据。理论上,单单依靠 MAC 地址,上海的网卡就可以找到洛杉矶的网卡了,技术上是可以实现的。

但是,这样做有一个重大的缺点。以太网采用广播方式发送数据包,所有成员人手一"包",不仅效率低,而且局限在发送者所在的子网络。也就是说,如果两台计算机不在同一个子网络,广播是传不过去的。这种设计是合理的,否则互联网上每一台计算机都会收到所有包,那会引起灾难。

互联网是无数子网络共同组成的一个巨型网络,很像想象上海和洛杉矶的电脑会在同一个子网络,这几乎是不可能的。

因此,必须找到一种方法,能够区分哪些 MAC 地址属于同一个子网络,哪些不是。如果是同一个子网络,就采用广播方式发送,否则就采用"路由"方式发送。("路由"的意思,就是指如何向不同的子网络分发数据包,这是一个很大的主题,本文不涉及。)遗憾的是,MAC 地址本身无法做到这一点。它只与厂商有关,与所处网络无关。

这就导致了"网络层"的诞生。它的作用是引进一套新的地址,使得我们能够区分不同的计算机是否属于同一个子网络。这套地址就叫做"网络地址"。

于是,"网络层"出现以后,每台计算机有了两种地址,一种是 MAC 地址,另一种是网络地址。两种地址之间没有任何联系,MAC 地址是绑定在网卡上的,网络地址则是管理员分配的,它们只是随机组合在一起。

网络地址帮助我们确定计算机所在的子网络,MAC 地址则将数据包送到该子网络中的目标网卡。因此,从逻辑上可以推断,必定是先处理网络地址,然后再处理MAC地址。

IP协议

规定网络地址的协议,叫做 IP 协议。它所定义的地址,就被称为 IP 地址。

目前,广泛采用的是 IP 协议第四版,简称 IPv4。这个版本规定,网络地址由 32 个二进制位组成。

习惯上,我们用分成四段的十进制数表示 IP 地址,从 0.0.0.0 一直到 255.255.255.255。

互联网上的每一台计算机,都会分配到一个 IP 地址。这个地址分成两个部分,前一部分代表网络,后一部分代表主机。比如,IP 地址 172.16.254.1,这是一个 32 位的地址,假定它的网络部分是前 24 位(172.16.254),那么主机部分就是后 8 位(最后的那个1)。处于同一个子网络的电脑,它们 IP 地址的网络部分必定是相同的,也就是说 172.16.254.2 应该与 172.16.254.1 处在同一个子网络。

但是,问题在于单单从 IP 地址,我们无法判断网络部分。还是以 172.16.254.1 为例,它的网络部分,到底是前 24 位,还是前 16 位,甚至前 28 位,从 IP 地址上是看不出来的。

那么,怎样才能从 IP 地址,判断两台计算机是否属于同一个子网络呢?这就要用到另一个参数"子网掩码"(subnet mask)。

所谓"子网掩码",就是表示子网络特征的一个参数。它在形式上等同于 IP 地址,也是一个 32 位二进制数字,它的网络部分全部为 1 ,主机部分全部为 0。比如,IP 地址 172.16.254.1,如果已知网络部分是前 24 位,主机部分是后 8 位,那么子网络掩码就是 11111111.11111111.11111111.00000000,写成十进制就是 255.255.255.0。

知道"子网掩码",我们就能判断,任意两个 IP 地址是否处在同一个子网络。方法是将两个 IP 地址与子网掩码分别进行 AND 运算(两个数位都为 1,运算结果为 1,否则为 0),然后比较结果是否相同,如果是的话,就表明它们在同一个子网络中,否则就不是。

比如,已知IP地址 172.16.254.1 和 172.16.254.233 的子网掩码都是 255.255.255.0,请问它们是否在同一个子网络?两者与子网掩码分别进行AND运算,结果都是 172.16.254.0,因此它们在同一个子网络。

总结一下,IP 协议的作用主要有两个,一个是为每一台计算机分配 IP 地址,另一个是确定哪些地址在同一个子网络。

IP 数据包

根据 IP 协议发送的数据,就叫做 IP 数据包。不难想象,其中必定包括 IP 地址信息。

但是前面说过,以太网数据包只包含 MAC 地址,并没有 IP 地址的栏位。那么是否需要修改数据定义,再添加一个栏位呢?

回答是不需要,我们可以把 IP 数据包直接放进以太网数据包的"数据"部分,因此完全不用修改以太网的规格。这就是互联网分层结构的好处:上层的变动完全不涉及下层的结构。

具体来说,IP数据包也分为"标头"和"数据"两个部分。

"标头"部分主要包括版本、长度、IP 地址等信息,"数据"部分则是 IP 数据包的具体内容。它放进以太网数据包后,以太网数据包就变成了下面这样。

IP 数据包的"标头"部分的长度为 20 到 60 字节,整个数据包的总长度最大为 65,535 字节。因此,理论上,一个 IP 数据包的"数据"部分,最长为 65,515 字节。前面说过,以太网数据包的"数据"部分,最长只有 1500 字节。因此,如果 IP 数据包超过了 1500 字节,它就需要分割成几个以太网数据包,分开发送了。

ARP 协议

关于"网络层",还有最后一点需要说明。

因为 IP 数据包是放在以太网数据包里发送的,所以我们必须同时知道两个地址,一个是对方的 MAC 地址,另一个是对方的 IP 地址。通常情况下,对方的 IP 地址是已知的(后文会解释),但是我们不知道它的 MAC 地址。

所以,我们需要一种机制,能够从 IP 地址得到 MAC 地址。

这里又可以分成两种情况。第一种情况,如果两台主机不在同一个子网络,那么事实上没有办法得到对方的 MAC 地址,只能把数据包传送到两个子网络连接处的"网关"(gateway),让网关去处理。

第二种情况,如果两台主机在同一个子网络,那么我们可以用 ARP 协议,得到对方的 MAC 地址。ARP 协议也是发出一个数据包(包含在以太网数据包中),其中包含它所要查询主机的 IP 地址,在对方的 MAC 地址这一栏,填的是FF:FF:FF:FF:FF:FF,表示这是一个"广播"地址。它所在子网络的每一台主机,都会收到这个数据包,从中取出 IP 地址,与自身的 IP 地址进行比较。如果两者相同,都做出回复,向对方报告自己的 MAC 地址,否则就丢弃这个包。

总之,有了 ARP 协议之后,我们就可以得到同一个子网络内的主机 MAC 地址,可以把数据包发送到任意一台主机之上了。

传输层

传输层的由来

有了 MAC 地址和 IP 地址,我们已经可以在互联网上任意两台主机上建立通信。

接下来的问题是,同一台主机上有许多程序都需要用到网络,比如,你一边浏览网页,一边与朋友在线聊天。当一个数据包从互联网上发来的时候,你怎么知道,它是表示网页的内容,还是表示在线聊天的内容?

也就是说,我们还需要一个参数,表示这个数据包到底供哪个程序(进程)使用。这个参数就叫做"端口"(port),它其实是每一个使用网卡的程序的编号。每个数据包都发到主机的特定端口,所以不同的程序就能取到自己所需要的数据。

"端口"是 0 到 65535 之间的一个整数,正好 16 个二进制位。0 到 1023 的端口被系统占用,用户只能选用大于 1023 的端口。不管是浏览网页还是在线聊天,应用程序会随机选用一个端口,然后与服务器的相应端口联系。

"传输层"的功能,就是建立"端口到端口"的通信。相比之下,"网络层"的功能是建立"主机到主机"的通信。只要确定主机和端口,我们就能实现程序之间的交流。 因此,Unix 系统就把主机+端口,叫做"套接字"(socket)。有了它,就可以进行网络应用程序开发了。

UDP 协议

现在,我们必须在数据包中加入端口信息,这就需要新的协议。最简单的实现叫做 UDP 协议,它的格式几乎就是在数据前面,加上端口号。

UDP 数据包,也是由"标头"和"数据"两部分组成。

"标头"部分主要定义了发出端口和接收端口,"数据"部分就是具体的内容。然后,把整个 UDP 数据包放入 IP 数据包的"数据"部分,而前面说过,IP 数据包又是放在以太网数据包之中的,所以整个以太网数据包现在变成了下面这样:

UDP 数据包非常简单,"标头"部分一共只有 8 个字节,总长度不超过 65,535 字节,正好放进一个 IP 数据包。

TCP 协议

UDP 协议的优点是比较简单,容易实现,但是缺点是可靠性较差,一旦数据包发出,无法知道对方是否收到。

为了解决这个问题,提高网络可靠性,TCP 协议就诞生了。这个协议非常复杂,但可以近似认为,它就是有确认机制的 UDP 协议,每发出一个数据包都要求确认。如果有一个数据包遗失,就收不到确认,发出方就知道有必要重发这个数据包了。

因此,TCP 协议能够确保数据不会遗失。它的缺点是过程复杂、实现困难、消耗较多的资源。

TCP 数据包和 UDP 数据包一样,都是内嵌在 IP 数据包的"数据"部分。TCP 数据包没有长度限制,理论上可以无限长,但是为了保证网络的效率,通常 TCP 数据包的长度不会超过 IP 数据包的长度,以确保单个 TCP 数据包不必再分割。

应用层

应用程序收到"传输层"的数据,接下来就要进行解读。由于互联网是开放架构,数据来源五花八门,必须事先规定好格式,否则根本无法解读。

"应用层"的作用,就是规定应用程序的数据格式。

举例来说,TCP 协议可以为各种各样的程序传递数据,比如 Email、WWW、FTP 等等。那么,必须有不同协议规定电子邮件、网页、FTP 数据的格式,这些应用程序协议就构成了"应用层"。

这是最高的一层,直接面对用户。它的数据就放在 TCP 数据包的"数据"部分。因此,现在的以太网的数据包就变成下面这样。

层级协议标头长度(字节)总长度限制(字节)数据长度限制(字节)
链路层以太网协议1864 ~ 151846 ~ 1500
网络层IP 协议20 ~ 606553565515
传输层TCP 协议无(一般不超过IP数据包长度)

HTTP 协议

HTTP/1.x

HTTP/1.x 已经是昨日黄花了(虽然现在绝大多数 HTTP 请求还是 HTTP/1.1  ̄□ ̄||),就不再多做介绍了。

HTTP/2

HTTP/2 是 HTTP 协议的第二个主要版本,由 IETF 的 HTTP 工作组开发,并于 2015 年发布。HTTP/2 的设计目标是提高 web 性能,减少延迟,并使服务器和客户端之间的数据传输更加高效。

HTTP/2 通过引入 Header 字段压缩,允许在同一连接上进行多个并发交换,可以更有效地利用网络资源并减少延迟感知。具体来说,它允许在同一个 TCP 连接上交替传递请求和响应消息,并使用高效的 HTTP Header 字段的编码。它还允许对请求进行优先级排序,让更重要的请求更快地完成,从而进一步提高性能。

由此产生的协议对网络更加友好,因为与 HTTP/1.x 相比,可以使用更少的 TCP 连接。这意味着与其他流的竞争更少,连接寿命更长,从而更好地利用可用网络容量。最后,HTTP/2 还可以通过使用二进制消息帧来更有效地处理消息。

要注意的的是,HTTP/2 只是扩展而不是取代以前的 HTTP 标准。 HTTP 的应用程序语义是相同的,并且没有对所提供的功能或核心概念(例如 HTTP 方法、状态代码、URI 和标头字段)进行任何更改。

二进制分帧

HTTP/2 所有性能增强的核心是新的二进制帧层,它规定了 HTTP 消息如何在客户端和服务器之间封装和传输。

二进制帧层

“层”是指在套接字接口和暴露给我们的应用程序的 HTTP API 之间引入新的优化编码机制。HTTP 语义,例如方法和标头等不受影响,主要是在传输过程中进行编码。与换行符分隔的纯文本 HTTP/1.x 协议不同,所有 HTTP/2 通信都分为更小的消息和帧,并以二进制格式编码。如果按照五层网络模型,可以理解是在传输层与应用层之间又增加了一层。

因此,客户端和服务器都必须使用新的二进制编码机制来相互理解:HTTP/1.x 客户端无法理解 HTTP/2 的服务器,反之亦然。

几个概念

Stream

已建立的连接内的双向字节流,可以携带一个或多个消息。

所有通信都是通过单个 TCP 连接执行的,该连接可以承载任意数量的双向流。 每个流都有一个唯一的标识符和用于承载双向消息的优先级信息。

Message

映射到逻辑请求或响应消息的完整帧序列。

每条消息都是逻辑 HTTP 消息,例如请求或响应,由一个或多个帧组成。

Frame

HTTP/2 中的最小通信单元,每个单元包含一个帧头,该帧头至少标识该帧所属的流。

帧是承载特定类型数据(例如 HTTP Header、消息体等)的最小通信单元。来自不同流的帧可以交错的传输,然后通过每个帧的标头中嵌入的流标识符重新组装。

connection

简而言之,HTTP/2 将 HTTP 协议通信分解为二进制编码帧的交换,然后将其映射到属于特定流的消息,并且所有这些消息都在单个 TCP 连接内进行并行传输。这是实现 HTTP/2 协议提供的所有其他功能和性能优化的基础。

多路复用

在 HTTP/1.x 中,如果客户端想要发出多个并行请求以提高性能,那么必须使用多个 TCP 连接。这是由 HTTP/1.x 的模型所决定的,该模型确保每个连接一次只能有一个响应(响应排队)。这会导致队头阻塞和底层 TCP 连接的使用效率低下。

HTTP/2 中新的二进制帧层消除了这些限制,允许客户端和服务器将 HTTP 消息分解为独立的帧,将它们交错的传递,然后在另一端重新组装,从而实现请求、响应的多路复用。

47ba5b32e42cf5a06c3741d29ef9b94a.svg

如图所示,客户端正在向服务器传输 DATA 帧(流 5),而服务器正在向客户端传输流 1 和 3 的交错帧序列结果,同一连接内出现了三个平行的流在传递。

单一链接

有了新的二进制帧机制,HTTP/2 不再需要多个 TCP 连接来才能实现并行;每个流被分成许多帧,这些帧可以交织并且有优先级的传输。因此,所有 HTTP/2 连接都是持久的,每个源只需要一个连接,这提供了许多性能优势。

大多数 HTTP 传输都是短暂且突发的,而 TCP 则是针对长期、批量数据传输进行了优化。通过复用相同的连接,HTTP/2 能够更有效地利用每个 TCP 连接,显著减少总体协议开销。此外,使用更少的连接可以减少整个连接路径(即客户端、中间链路和服务器)的内存和处理占用,从而降低总体运营成本并提高网络利用率和容量。因此,转向 HTTP/2 不仅能减少网络延迟,还有助于提高吞吐量并降低运营成本。

流量控制

流量控制是一种防止发送方发送大量无效或无法处理的数据淹没接收方的机制:接收方可能很忙、负载很重,或者可能只愿意为特定的数据分配固定数量的资源。例如,客户端可能请求了高优先级的大视频流,但用户已暂停视频,并且客户端现在想要暂停或限制其从服务器的传送,以避免获取和缓冲不必要的数据。或者,代理服务器可能具有快速的下游和慢速的上游,希望调节下游传输数据的速度以匹配上游的速度,从而控制其资源使用;等等。

上述要求是否让你想起了 TCP 流控?由于 HTTP/2 流在单个 TCP 连接内进行多路复用,因此 TCP 流控机制的粒度不够细,并且没有提供必要的应用程序级 API 来调节各个流的传送。为了解决这个问题,HTTP/2 提供了一组简单的模块,允许客户端和服务器实现自己的 stream 级别和 connection 级别的流量控制。

HTTP/2 没有指定任何特定的算法来实现流量控制。而是提供了简单的模块并将实现交由到客户端和服务器,客户端和服务器可以使用它来实现自定义策略来调节资源使用和分配,这有助于提高 Web 应用程序的实际性能和感知能力。

服务端推送

HTTP/2 的另一个强大的新功能是服务器能够针对单个客户端请求发送多个响应。也就是说,除了对原始请求的响应之外,服务器还可以向客户端推送其他资源,而客户端无需显式地请求每一项资源!

d759887277b266a42c526643285dd244.svg

HTTP/2 摆脱了严格的请求响应语义,支持一对多和服务器启动的推送工作流。

为什么我们在浏览器中需要这样的机制?典型的 Web 应用程序由数十个资源组成,所有这些资源都是客户端通过请求服务器上的内容来获得。那么,为什么不消除额外的延迟并让服务器提前推送相关资源呢?

Header 压缩

每个 HTTP 请求都带有一组描述其请求的 Header。在 HTTP/1.x 中,这些元数据始终以纯文本形式发送,每次传输会增加 500-800 字节的开销,如果使用 HTTP cookie,有时会增加数千字节的开销。为了减少这种开销并提高性能,HTTP/2 使用 HPACK 压缩格式来压缩请求和响应的 Header 数据,该格式使用两种简单但强大的技术:

  • 它允许通过 Huffman code 对传输的 Header 字段进行编码,从而减少了传输大小。
  • 它要求客户端和服务器维护和更新先前传输的 Header 字段的索引列表(即建立共享上下文),然后将其用作于后面的传输。

feb142f82737d148ed5bcefd91915276.svg

HPACK 压缩上下文由静态表和动态表组成:静态表在规范中定义,并提供所有可能使用的公共 HTTP Header 字段列表;动态表最初是空的,并基于连接内交换的值进行更新。因此,通过对以前没有见过的值使用 Huffman code,并用索引替换每一侧静态或动态表中已经存在的值,可以减少每个请求的大小。

HTTP/3

HTTP/3 是 HTTP 协议的第三个主要版本,同样由 IETF 的 HTTP 工作组开发,于 2018 年发布。它是基于 QUIC 协议构建的,旨在解决 HTTP/2 的某些缺点,进一步提高网络性能和可靠性。

HTTP/2 和 HTTP/3 之间最主要的区别在于它们的底层传输协议 TCP 和 QUIC。HTTP/2 是基于 TCP 协议的,TCP 协议是数十年来互联网通信的支柱,可在应用程序之间提供可靠、有序的字节流传输。然而,它也存在着一些问题。

TCP 的局限性

现在大多数 TCP 协议版本都通过要求按顺序处理数据包来确保数据完整性。因此无论 TCP 什么版本,应用程序层都无法读取正在传输的结果,直到按顺序接收到它们为止。如果数据包丢失,后续数据包必须等待,直到丢失的数据包被重新传输并被接收。这会导致多路复用连接中的延迟和队头阻塞。

另一个缺点是建立 TCP 连接需要三次握手。在需要往返服务器的连接建立过程,会引入明显的延迟。

QUIC 的优势

基于 QUIC 的 HTTP/3 在 UDP 上运行。与 TCP 不同,QUIC 旨在提供更好的可靠性和安全性,同时解决 TCP 的局限性。

  • QUIC 通过允许互不阻塞的独立数据流解决了队头阻塞问题。它对数据包丢失和网络条件更具弹性。
  • QUIC 将加密握手(使用 TLS 1.3)纳入其连接建立过程。它减少了建立安全连接所需的往返次数。

Handshake process between HTTP/2 and HTTP/3

多路复用

HTTP/2 局限性

尽管存在多路复用,但 TCP 的顺序性会导致大多数 TCP 链接中出现队头部阻塞。当特定流(多路复用连接内的单个请求/响应周期)的第一个数据包(“头”)延迟或丢失时,就会发生队头阻塞。在丢失的数据包到达之前,无法处理后续数据包。这意味着即使 HTTP/2 可以并行处理多个请求,但在头部数据包到达之前它无法这样做。

另一个问题是,虽然 HTTP/2 理论上支持 Stream 优先级,但底层 TCP 连接无法区分流,可能导致资源分配不理想。

HTTP/3 多路复用及优先级

在 HTTP/3 中,每个流都是独立的。如果丢包,只有受影响的流需要等待重传,而其他流不受影响,从而显著改善丢包情况下的网络体验。因此,HTTP/3 不会受到 TCP 队头阻塞的影响。

HTTP/3 还可以更有效地管理流优先级。流优先级是对某些特定类型的数据进行优先级排序的功能,以便它们可以跳过排队更快地处理完成。这很有用,因为在浏览网页或使用应用程序时,并非所有数据都同样重要。这种技术可以让你在不太重要的项目之前就获取文本和主图像,这样你就可以开始阅读,而无需等待每个小细节加载。

在 HTTP/2 中,优先级指令被发送到服务器,但实际的优先级可能会受到 TCP 队头阻塞的阻碍。

相比之下,HTTP/3 对优先级控制提供更精细的粒度和可靠性。 QUIC 连接可以处理不同数据类型的多个独立流,从而更有效地利用关键网络资源。

Multiplexing HTTP/2 vs HTTP/3

建立链接

常规 TCP 使用三向握手。

SYN:客户端向服务器发送同步数据包。

SYN-ACK:服务器确认并用其同步数据包进行响应。

ACK:客户端确认服务器响应并建立连接。

这种方法虽然可靠,但从一开始就引入了延迟。在此之后,使用安全连接 (TLS) 会增加另一轮交换,进一步加剧延迟并影响整体用户体验。

HTTP/3 在 UDP 上使用 QUIC。一般来说,UDP 不需要握手后开始发送数据。不过,为了安全起见,QUIC 引入了自己的握手机制。它结合了连接和加密握手,减少了建立安全连接的步骤。它支持到同一服务器的连接的 0-RTT(往返时间),使数据传输能够从第一个数据包开始。尽管速度加快,但安全性并未受到损害,因为它从一开始就融入了最新的加密标准 (TLS 1.3),

安全性

TLS 1.2 局限性

虽然 TLS 1.2 及更高版本提供强大的安全功能,但它们还需要仔细配置以避免漏洞并确保兼容性。客户端和服务器之间支持的密码套件不匹配、使用已弃用的加密算法以及管理证书的开销可能会使部署复杂化并影响性能和安全性。

TCP 和 TLS 的综合开销也可能会占用服务器资源。这可能会导致可扩展性挑战,因为每个连接都需要自己的加密和状态管理资源。

新的或“冷”的 TCP 连接,尤其是那些协商 TLS 的连接,在达到最佳性能之前可能会经历一段“预热”时间。这是由于 TCP 的慢启动机制以及协商和缓存 TLS 会话密钥需要时间。

TLS 1.3 优势

HTTP/3 集成了最新版本的加密协议 TLS 1.3,简化并增强了安全机制,删除了过时的密码套件以及与旧版本相关的漏洞。它确保每个连接都有唯一的加密密钥。即使长期密钥被泄露,过去的通信仍然安全。

错误恢复

网络拥塞、基础设施故障和其他问题会导致互联网上的数据包丢失。 HTTP/2 依赖 TCP 来发现并解决问题。 TCP 在确保数据完整且有序方面做得很好,但该过程可能很慢。

HTTP/3 包括前向纠错 (FEC) 机制。这就像为你的数据包制定一个备份计划;如果某些数据在传输过程中丢失,其他数据中包含的信息足以在接收端重建丢失的内容,而无需重新发送任何数据。

服务端推送

HTTP/2 引入了服务器推送,作为服务器预先向客户端发送资源(例如渲染网页所需的 CSS 或 JavaScript 文件)的一种方式,而无需等待浏览器请求它们。这个想法是通过消除浏览器和服务器之间的往返来节省时间并更快地加载网页。然而,也存在挑战:

  • 有时,服务器可能会推送浏览器已缓存的资源,从而导致带宽浪费。
  • 浏览器无法告诉服务器它们需要什么,使得不需要的服务器推送变得更加常见。

尽管意图良好,但由于效率低下,HTTP/2 中的服务器推送并不总是能够充分发挥其潜力。

相比之下,HTTP/3 提供了一种机制,可以让客户端和服务器之间就应该推送的内容进行更好的通信,从而减少浪费的数据传输。例如,客户端可以使用 SETTINGS 框架来调整他们愿意处理的并发推送数量,甚至完全禁用服务器推送。

此外,HTTP/3 中改进的多路复用和流优先级意味着,如果同时发送其他内容,服务器推送不太可能堵塞网络。

网络变化

由于 HTTP/2 和 TCP 连接与 IP 地址紧密相关,因此在移动网络状态可能面临很大的挑战。因为,当您的设备从一个网络切换到另一个网络(例如,从家庭 Wi-Fi 切换到移动网络)时,通常意味着您的 IP 地址发生变化。 TCP 不能很好地处理这种变化;它需要重新建立连接,这可能会中断您正在执行的任何操作。

HTTP/3 旨在更平滑地处理这些场景,因为它不依赖 IP 地址来维持连接。相反,它使用连接 ID 功能。它为每个连接分配一个唯一的 ID,即使底层网络发生变化,该 ID 也保持不变。

这意味着,如果您的设备切换网络,它可以保持连接并防止中断。正在进行的活动(如视频通话或文件传输)将继续进行,不会中断。

总结

HTTP/3 在 UDP 协议上使用 QUIC,通过消除队头阻塞、减少延迟以及增强整体 Web 性能和安全性来解决 HTTP/2 的局限性。无论用户网络环境如何变化,都能保证更快、更安全的在线体验,服务不间断。集成 Catchpoint 等工具可以进一步优化和了解这些功能的影响。

互联网协议入门(一)

互联网协议入门(二)

HTTP/2

HTTP/3 vs. HTTP/2 — A detailed comparison