目标
- 建立对计算机网络的整体认知
- 可以在后续的实际工作中能高效解决网络问题。
1 内容介绍
- 通过一个示例建立对计算机网络的整体认识
- 建立对网络协议分层的认知
- 分析方法
- 自底向上
- 从简单开始,逐渐变复杂
- 将模块逐步拼凑成一个系统
- 自顶向下
- 从复杂开始,逐渐变简单
- 从复杂的系统问题入手,拆分为模块问题
- 自底向上
2 Web中的网络
2.1 HTTP1
- 请求代码
- 如下
GET /index.html HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Connection: keep-alive
-
参数说明:
-
请求行(Request Line):
GET /index.html HTTP/1.1。请求行包含了请求方法(GET)、请求资源的路径(/index.html)和 HTTP 协议版本(HTTP/1.1)。 -
Host:
www.example.com。Host 头部指定了请求的目标服务器域名。 -
User-Agent:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36。User-Agent 头部描述了发起请求的客户端(浏览器)的信息,包括操作系统、浏览器类型和版本等。 -
Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8。Accept 头部表示客户端支持接收的 MIME 类型。在这个示例中,客户端支持接收 HTML、XHTML、XML 和 WebP 等格式的内容。 -
Accept-Language:
en-US,en;q=0.5。Accept-Language 头部表示客户端支持的语言和优先级。在这个示例中,客户端优先支持美国英语,其次是其他英语。 -
Connection:
keep-alive。Connection 头部表示连接的控制选项。在这个示例中,keep-alive 表示客户端希望保持连接,以便在多个请求之间复用 TCP 连接。
-
-
响应
- HTTP 协议中的响应是服务器针对客户端请求所作出的回应。响应消息包含状态行、响应头部和响应体三部分。以下是一个简化的 HTTP 响应示例:
HTTP/1.1 200 OK Date: Mon, 23 May 2022 22:38:34 GMT
Server: Apache/2.4.1 (Unix) Content-Type: text/html; charset=UTF-8 Content-Length: 138
Last-Modified: Sun, 22 May 2022 15:28:12 GMT
Connection: close
<!DOCTYPE html>
<html>
<head>
<title>Example Page</title>
</head>
<body>
<h1>Hello, XiaoYu!</h1>
</body>
</html>
- 参数说明:
-
状态行(Status Line):
HTTP/1.1 200 OK。状态行包含 HTTP 协议版本(HTTP/1.1)、状态码(200)和状态描述(OK)。状态码 200 表示请求已成功处理。 -
Date:
Mon, 23 May 2022 22:38:34 GMT。Date 头部表示响应生成的日期和时间。 -
Server:
Apache/2.4.1 (Unix)。Server 头部描述了生成响应的服务器软件和版本信息。 -
Content-Type:
text/html; charset=UTF-8。Content-Type 头部指定了响应体的媒体类型(MIME 类型)和字符编码。在这个示例中,响应体的内容是 HTML 格式,字符编码为 UTF-8。 -
Content-Length:
138。Content-Length 头部表示响应体的字节长度。 -
Last-Modified:
Sun, 22 May 2022 15:28:12 GMT。Last-Modified 头部表示请求资源的最后修改时间。 -
Connection:
close。Connection 头部表示连接的控制选项。在这个示例中,close 表示服务器在发送完响应后将关闭 TCP 连接。 -
响应体(Response Body):响应体包含实际返回的数据,通常是 HTML、JSON、XML 等格式的内容。在这个示例中,响应体是一个简单的 HTML 页面。
-
2.2 HTTP连接模型
- 无连接模型
- 在早期的 HTTP/1.0 版本中,HTTP 使用无连接模型。
- 这意味着每个 HTTP 请求和响应都需要建立一个新的 TCP 连接,在处理完一个请求后,服务器会关闭连接。
- 这种模型简单易实现,但在高延迟和大量并发请求的场景下,性能较差。每个连接的建立和关闭都会消耗资源和时间,导致延迟增加和服务器负载过高。
- 持久连接模型
- 为了解决无连接模型的性能问题,HTTP/1.1 引入了持久连接(Persistent Connection)模型,也称为 Keep-Alive 连接。
- 在持久连接模型中,客户端和服务器可以在一个 TCP 连接上发送多个 HTTP 请求和响应。
- 这种模型减少了 TCP 连接的建立和关闭次数,降低了延迟和服务器负载,提高了性能。
- 持久连接在 HTTP/1.1 中是默认启用的,可以通过 Connection 请求头部的值(Keep-Alive 或 close)进行控制。
- 管道化连接模型
- HTTP/1.1 还引入了管道化(Pipelining)连接模型
- 它允许客户端在收到上一个请求的响应之前,连续发送多个请求。服务器会按照请求的顺序依次处理,并按顺序返回响应。
- 这种模型进一步提高了连接的利用率和性能。但由于实际部署中的兼容性和实现问题,HTTP/1.1 的管道化并未广泛应用。
2.3 队头堵塞
HTTP1.1:无法多路复用
-
HTTP/1.1 无法实现多路复用的主要原因是其基于文本的请求和响应格式以及协议设计。
- 在 HTTP/1.1 中,每个请求和响应都是一个完整的文本消息,必须按照顺序发送和接收。
- 这导致了一种称为“队头阻塞”(Head-of-Line Blocking)的问题,即一个请求或响应的处理延迟会影响后续的请求和响应,无法并行处理。
- 虽然 HTTP/1.1 引入了管道化技术以尝试提高性能,但由于实际部署中的兼容性和实现问题,管道化并未广泛应用。
-
HTTP/2有所优化:
- HTTP/2 通过引入二进制分帧、流、优先级和依赖以及流量控制等机制,实现了多路复用,克服了 HTTP/1.1 中队头阻塞等性能问题。
- 这些改进使得 HTTP/2 能在一个 TCP 连接上并行处理多个请求和响应,提高了性能和资源利用率。
- 多路复用连接模型: 在 HTTP/2 中,引入了多路复用(Multiplexing)连接模型。
- 多路复用允许客户端和服务器在一个 TCP 连接上并行发送和接收多个请求和响应。
- HTTP/2 通过将请求和响应拆分为多个帧(Frame),并为每个请求分配一个独立的流(Stream)来实现多路复用。
- 这种模型进一步提高了连接的利用率和性能,解决了 HTTP/1.1 管道化模型的问题。
- HTTP/2 还引入了其他优化措施,如头部压缩、服务器推送等,进一步提升了性能。
相比之下,HTTP/2 能实现多路复用的原因如下:
- 二进制分帧
- HTTP/2 把请求和响应分解为多个二进制帧,每个帧都有一个唯一的标识符。
- 这使得客户端和服务器能够在一个 TCP 连接上同时发送和接收多个请求和响应的帧,而不会产生队头阻塞问题。
- 流(Stream)
- HTTP/2 引入了流的概念,每个请求和响应都有一个独立的流。
- 流可以并行处理,每个流的帧可以独立发送和接收,而不受其他流的影响。
- 这使得多个请求和响应可以在一个 TCP 连接上并行传输,实现多路复用。
- 优先级和依赖
- HTTP/2 还支持为每个流设置优先级和依赖关系。
- 客户端可以通过优先级和依赖信息告诉服务器哪些请求更重要,哪些请求需要先完成。
- 以上述方法,服务器可以更有效地利用资源,优先处理重要的请求,进一步提高性能。
- 流量控制
- HTTP/2 引入了更为精细的流量控制机制,客户端和服务器可以独立地为每个流设置发送窗口大小,以控制每个流的传输速率。
- 这有助于避免一个流占用过多带宽,影响其他流的传输。
2.4 HTTP/2 帧
-
在 HTTP/2 中,帧(Frame)是协议的基本传输单位。
-
HTTP/2 将请求和响应消息分解为多个小的二进制帧,这些帧在客户端和服务器之间传输。每种类型的帧都有特定的目的和格式。
-
使用帧可以实现更高效的多路复用,避免队头阻塞问题,提高传输性能。
-
一个 HTTP/2 帧由以下几部分组成:
- 长度(Length):一个 24 位无符号整数,表示帧的负载长度(不包括帧头部的 9 个字节)。长度最大值为 2^24 - 1 字节(约 16MB)。
- 类型(Type):一个 8 位无符号整数,表示帧的类型。不同类型的帧用于传输不同类型的信息,如 HEADERS、DATA、SETTINGS 等。
- 标志(Flags):一个 8 位无符号整数,表示帧的特定属性。每种类型的帧都有自己的标志集合,用于控制帧的行为。
- 保留位(R):一个 1 位保留位,目前未使用,必须设置为 0。
- 流标识符(Stream Identifier):一个 31 位无符号整数,表示帧所属的流。流是 HTTP/2 中的一个基本概念,每个请求和响应都有一个独立的流。流标识符为 0 的帧表示与整个连接相关的控制帧,而非特定流。
- 负载(Payload):帧的负载数据,长度由 Length 字段指定。负载的内容和格式取决于帧的类型和标志。
-
HTTP/2 定义了以下几种类型的帧:
- DATA:用于传输请求或响应的主体数据。
- HEADERS:用于传输请求或响应的头部信息。HEADERS 帧可以与 CONTINUATION 帧一起传输较大的头部信息。
- PRIORITY:用于为流设置优先级和依赖关系。
- RST_STREAM:用于终止一个流,表示发生了错误或者不再需要传输该流的数据。
- SETTINGS:用于在客户端和服务器之间交换配置参数。
- PUSH_PROMISE:用于服务器向客户端推送资源,提前发送关联资源的头部信息,提高性能。
- PING:用于测量最小往返时间以及检测连接是否活跃。
- GOAWAY:用于通知对端关闭连接,可以包含诊断信息。
- WINDOW_UPDATE:用于实现流量控制,调整发送窗口大小。
- CONTINUATION:用于在 HEADERS 帧之后继续传输头部信息。
-
通过对请求和响应进行二进制分帧处理,HTTP/2 实现了更高效的传输和多路复用。以下是 HTTP/2 帧处理的一些主要优点:
- 多路复用:由于每个帧都有一个关联的流,客户端和服务器可以在单个 TCP 连接上同时发送和接收多个请求和响应。这避免了 HTTP/1.1 中的队头阻塞问题,提高了传输性能和资源利用率。
- 优先级和依赖:HTTP/2 允许为每个流设置优先级和依赖关系。客户端可以通过 PRIORITY 帧告诉服务器哪些请求更重要,哪些请求需要先完成。这使服务器能够更有效地分配资源,提高传输性能。
- 流量控制:HTTP/2 引入了更为精细的流量控制机制。客户端和服务器可以通过 WINDOW_UPDATE 帧独立地为每个流设置发送窗口大小,以控制每个流的传输速率。这有助于避免一个流占用过多带宽,影响其他流的传输。
- 服务器推送:HTTP/2 支持服务器推送功能,允许服务器在客户端请求之前主动发送资源。服务器可以通过发送 PUSH_PROMISE 帧,提前发送关联资源的头部信息,以提高页面加载性能。
- 头部压缩:HTTP/2 采用 HPACK 压缩算法对请求和响应头部进行压缩,以减少头部数据的大小。这有助于降低传输延迟,提高性能。
-
帧来带来的好处
- 调整响应传输的优先级
- 头部压缩
- Server Push
-
HTTP3出现的原因:HTTP3出现的原因是HTTP2还不够快和解决 HTTP/2 中仍然存在的一些问题和局限性
2.5 HTTP3 QUIC
-
定义:Quick UDP Internet Connection
- 现存网络设备对TCP和UDP支持已经僵化
- UDP不靠谱(包丢了就不管了,业务给多少数据,它就发多少数据)但是QUIC靠谱
- QUIC可以为除HTTP协议以外的应用层协议提供支持
-
HTTP/3 的出现主要是为了解决 HTTP/2 在面对丢包和网络不稳定的情况下的性能问题。通过引入基于 UDP 的 QUIC 协议,HTTP/3 解决了队头阻塞问题,实现了更快的连接建立和连接迁移,提高了错误恢复效率。这使得 HTTP/3 在网络环境不佳的情况下仍能提供良好的性能和用户体验。
-
性能问题:
-
队头阻塞问题(Head-of-Line Blocking):尽管 HTTP/2 引入了多路复用和二进制分帧来解决 HTTP/1.1 中的队头阻塞问题,但在 HTTP/2 中,所有的流都共享一个 TCP 连接。当 TCP 连接上的一个数据包丢失时,整个连接上的所有流都会受到影响,导致延迟增加。这种情况在丢包率较高的网络环境中尤为明显。
-
TCP 和 TLS 握手:HTTP/2 基于 TCP 协议,建立一个新连接时需要进行 TCP 三次握手。如果使用 HTTPS(基于 TLS 的 HTTP),还需要进行 TLS 握手。这些握手过程增加了连接建立的延迟。特别是在移动网络环境中,这种延迟可能对用户体验产生较大影响。
-
连接迁移:HTTP/2 基于 TCP,当用户设备的网络环境发生变化时(例如,从 Wi-Fi 切换到蜂窝网络),TCP 连接可能需要重新建立,导致延迟和资源浪费。HTTP/2 不支持连接迁移,无法实现平滑的网络切换。
-
-
为了解决上述问题,HTTP/3 引入了一个新的传输层协议——QUIC(Quick UDP Internet Connections)。QUIC 基于 UDP(User Datagram Protocol),而非 TCP,具有以下优势:
-
避免队头阻塞:QUIC 支持多路复用,且每个流在传输层上独立处理,因此一个流上的数据包丢失不会影响其他流。这样,在面对丢包和网络不稳定的情况下,QUIC 可以在面对丢包和网络不稳定的情况下,QUIC 可以实现更低的延迟,提高性能和用户体验。
-
更快的连接建立:由于 QUIC 基于 UDP,它将传输层和加密层的握手过程合并,从而减少了握手次数。这可以减少连接建立的延迟,尤其在网络环境不佳的情况下,对用户体验有很大帮助。
-
连接迁移:QUIC 支持连接迁移,当用户设备的网络环境发生变化时,可以实现平滑地从一个网络切换到另一个网络,而不会影响到已有的连接。这有助于减少延迟和资源浪费,提高用户体验。
-
错误恢复:QUIC 在丢包恢复方面比 TCP 更加高效,因为它可以更快地识别丢失的数据包并进行重传。这有助于减少延迟和提高传输性能。
-
3 总结
- 对于http系列有很详细的描述。
- 对于自己重复学习计网感到十分开心,狠狠地恶补了知识,努力学牢基础
- 很开心自己的学习有所产出,以后复习时候也可以拿自己文章来复习