Files
sanbuphy df51f84ab5 docs: 重构 README 附录展示 & 新增多个附录交互组件
README 更新:
- 移除顶部 header.png 横幅图片
- 新增「附录知识库」板块,以 3×3 网格展示 9 大知识领域精选内容
- 附录链接指向部署版网站 (datawhalechina.github.io)
- 阶段表格新增「附录」行,突出 80+ 交互式专题
- 章节标题「新手入门 & PM」简化为「零基础入门」
- News 新增 2026-02-25 附录知识库更新条目

新增交互组件:
- 异步任务队列 (async-task-queues) 演示组件
- 文件存储 (file-storage) 演示组件
- 项目架构 (project-architecture) 演示组件
- 限流与背压 (rate-limiting) 演示组件
- 搜索引擎 (search-engines) 演示组件
- 计算机基础: AppLaunch/BiosUefi/OSBoot 等启动流程演示组件

新增附录文档:
- 前端项目架构 (frontend-project-architecture.md)
- 后端项目架构 (backend-project-architecture.md)

内容优化:
- 算法思维、数据结构、编程语言、调试艺术等多篇附录内容更新
- HTML/CSS 布局、请求旅程等前后端文档完善
- 附录索引页 (index.md) 同步更新
2026-02-25 12:22:49 +08:00

296 lines
9.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 一个请求的完整旅程
::: tip 前言
**当你在浏览器里输入一个网址按下回车,到页面显示出来,中间到底发生了什么?** 这个问题是面试经典题,更是理解整个 Web 架构的钥匙。搞懂这条链路,你就能理解前端、后端、网络、数据库是怎么协作的。
:::
**这篇文章会带你学什么?**
学完这章后,你将获得:
- **全链路视角**:理解一个 HTTP 请求从发出到返回的完整过程
- **各层职责认知**:DNS、TCP、负载均衡、Web 服务器、应用服务器、数据库各自做什么
- **问题定位能力**:请求慢或失败时,知道从哪一层开始排查
- **性能优化思路**:每一层都有优化空间,知道优化点在哪里
| 章节 | 内容 | 核心概念 |
|-----|------|---------|
| **第 1 章** | 浏览器发起请求 | DNS 解析、TCP 连接、HTTP 请求 |
| **第 2 章** | 网络传输 | 路由、CDN、负载均衡 |
| **第 3 章** | 服务器处理 | Web 服务器、应用逻辑、数据库查询 |
| **第 4 章** | 响应返回 | 序列化、压缩、渲染 |
| **第 5 章** | 全链路优化 | 缓存、连接复用、异步处理 |
---
## 0. 全景图:一个请求经历了什么?
用一个比喻来理解:你在网上下单买书,这个过程和 HTTP 请求惊人地相似。
| 请求阶段 | 买书类比 | 技术对应 |
|---------|---------|---------|
| 输入网址 | 你说"我要去某某书店" | 浏览器解析 URL |
| DNS 解析 | 查地图找到书店地址 | 域名 → IP 地址 |
| TCP 连接 | 走到书店门口,推门进去 | 三次握手建立连接 |
| 发送请求 | 告诉店员"我要《xxx》这本书" | HTTP 请求报文 |
| 服务器处理 | 店员去仓库找书、查库存、算价格 | 应用逻辑 + 数据库查询 |
| 返回响应 | 店员把书递给你 | HTTP 响应报文 |
| 浏览器渲染 | 你打开书开始阅读 | HTML/CSS/JS 解析渲染 |
<RequestJourneyFlow />
---
## 1. 浏览器发起请求
### 1.1 URL 解析
当你输入 `https://api.example.com/books?id=123` 时,浏览器会把它拆解成几个部分:
| 部分 | 值 | 含义 |
|-----|-----|------|
| 协议 | `https` | 用加密方式通信 |
| 域名 | `api.example.com` | 服务器的"名字" |
| 路径 | `/books` | 要访问的资源 |
| 查询参数 | `id=123` | 附加条件 |
### 1.2 DNS 解析:域名 → IP 地址
计算机不认识域名,只认识 IP 地址(如 `93.184.216.34`)。DNS 就是互联网的"电话簿"。
```
浏览器缓存 → 系统缓存 → 路由器缓存 → ISP DNS → 根域名服务器
↓ 命中就直接用,不命中就往下查
```
::: tip DNS 缓存的意义
如果每次请求都从根域名服务器查起,全球互联网会被 DNS 查询压垮。所以每一层都有缓存,大部分请求在浏览器或系统层就能解析完成。
:::
### 1.3 TCP 三次握手
找到 IP 地址后,浏览器需要和服务器"建立连接"。TCP 用三次握手确保双方都准备好了:
```
客户端 → 服务器:你好,我想连接(SYN)
服务器 → 客户端:好的,我准备好了(SYN + ACK)
客户端 → 服务器:收到,开始通信(ACK)
```
如果是 HTTPS,还需要额外的 TLS 握手来协商加密方式。
### 1.4 发送 HTTP 请求
连接建立后,浏览器发送 HTTP 请求报文:
```http
GET /books?id=123 HTTP/1.1
Host: api.example.com
Accept: application/json
Authorization: Bearer eyJhbGci...
User-Agent: Chrome/120.0
```
| 组成部分 | 内容 |
|---------|------|
| 请求行 | 方法(GET)+ 路径 + 协议版本 |
| 请求头 | 元信息:身份认证、期望的数据格式等 |
| 请求体 | POST/PUT 请求才有,携带要提交的数据 |
---
## 2. 网络传输:请求在路上
### 2.1 路由转发
请求离开你的电脑后,会经过多个路由器的转发,就像快递经过多个中转站:
```
你的电脑 → 家庭路由器 → 运营商网络 → 骨干网 → 目标机房
```
每个路由器根据 IP 地址决定"下一跳"往哪里转发。可以用 `traceroute` 命令查看请求经过了哪些节点。
### 2.2 CDN 加速
如果目标网站使用了 CDN(内容分发网络),请求可能不需要到达源服务器:
| 场景 | 走向 |
|-----|------|
| 请求静态资源(图片、CSS、JS) | CDN 边缘节点直接返回 |
| 请求动态数据(API) | 穿透 CDN,到达源服务器 |
CDN 的本质是"把内容提前放到离用户最近的地方"。
### 2.3 负载均衡
大型网站不会只有一台服务器。负载均衡器负责把请求分配到多台服务器上:
```
用户请求 → 负载均衡器 → 服务器 A(30% 流量)
→ 服务器 B(30% 流量)
→ 服务器 C(40% 流量)
```
常见的分配策略:
| 策略 | 原理 | 适用场景 |
|-----|------|---------|
| 轮询 | 依次分配 | 服务器配置相同 |
| 加权轮询 | 按权重分配 | 服务器配置不同 |
| IP 哈希 | 同一用户固定到同一台 | 需要会话保持 |
| 最少连接 | 分给当前连接最少的 | 请求处理时间差异大 |
---
## 3. 服务器处理:厨房里发生了什么
请求到达服务器后,会经过多层处理。
### 3.1 Web 服务器(Nginx / Apache
第一个接收请求的通常是 Web 服务器,它负责:
| 职责 | 说明 |
|-----|------|
| 静态文件服务 | 直接返回 HTML、CSS、JS、图片 |
| 反向代理 | 把 API 请求转发给后端应用 |
| SSL 终止 | 处理 HTTPS 加密解密 |
| 请求过滤 | 拦截恶意请求、限流 |
### 3.2 应用服务器处理
Web 服务器把请求转发给应用服务器(Node.js、Spring、Django 等),处理流程:
```
请求进入 → 中间件链 → 路由匹配 → 控制器 → 服务层 → 数据访问层
```
**中间件**做的事情:
1. 解析请求体(JSON、表单数据)
2. 验证身份(检查 Token
3. 检查权限(这个用户能访问这个接口吗?)
4. 记录日志(谁在什么时候访问了什么)
### 3.3 数据库查询
大部分请求最终都要和数据库打交道:
```
应用代码:SELECT * FROM books WHERE id = 123
数据库引擎:解析 SQL → 查询优化 → 执行计划 → 读取数据
返回结果:{ id: 123, title: "xxx", price: 59.9 }
```
::: tip 数据库是最常见的性能瓶颈
网络传输通常是毫秒级,应用逻辑也很快,但一个没有索引的数据库查询可能要几秒甚至几十秒。所以"慢请求"大概率是数据库查询慢。
:::
---
## 4. 响应返回:数据的归途
### 4.1 构造 HTTP 响应
服务器处理完后,构造响应报文:
```http
HTTP/1.1 200 OK
Content-Type: application/json
Content-Encoding: gzip
Cache-Control: max-age=3600
```
| 组成部分 | 内容 |
|---------|------|
| 状态行 | 协议版本 + 状态码(200 成功、404 未找到、500 服务器错误) |
| 响应头 | 数据格式、缓存策略、压缩方式等 |
| 响应体 | 实际的数据内容(JSON、HTML 等) |
### 4.2 数据压缩
服务器通常会用 gzip 或 brotli 压缩响应体,减少传输量:
| 压缩算法 | 压缩率 | 速度 |
|---------|--------|------|
| gzip | 约 70% | 快 |
| brotli | 约 80% | 较慢但压缩更好 |
一个 100KB 的 JSON,压缩后可能只有 20-30KB。
### 4.3 浏览器渲染
浏览器收到响应后:
1. **解析 HTML** → 构建 DOM 树
2. **解析 CSS** → 构建样式树
3. **合并** → 生成渲染树
4. **布局** → 计算每个元素的位置和大小
5. **绘制** → 把像素画到屏幕上
<RequestTimeline />
---
## 5. 全链路优化:每一层都能更快
### 5.1 各层优化手段
| 层级 | 优化手段 | 效果 |
|-----|---------|------|
| DNS | DNS 预解析、使用快速 DNS 服务 | 减少 DNS 查询时间 |
| 网络 | CDN、HTTP/2、连接复用 | 减少传输延迟 |
| 服务器 | 缓存(Redis)、异步处理 | 减少处理时间 |
| 数据库 | 索引、查询优化、读写分离 | 减少查询时间 |
| 前端 | 懒加载、代码分割、资源压缩 | 减少渲染时间 |
### 5.2 缓存:最有效的优化
缓存存在于请求链路的每一层:
```
浏览器缓存 → CDN 缓存 → 反向代理缓存 → 应用缓存(Redis)→ 数据库缓存
```
::: tip 缓存的本质
用空间换时间。把计算过的结果存起来,下次直接用,不用重新算。缓存命中率每提高 10%,系统性能可能提升数倍。
:::
### 5.3 请求失败时的排查思路
| 现象 | 可能的问题层 | 排查方法 |
|-----|------------|---------|
| 完全无响应 | DNS / 网络 | ping、nslookup |
| 连接超时 | 网络 / 服务器宕机 | telnet、curl |
| 返回 4xx | 客户端请求有误 | 检查 URL、参数、Token |
| 返回 5xx | 服务器内部错误 | 查看服务器日志 |
| 响应很慢 | 数据库 / 应用逻辑 | 查看慢查询日志、APM 工具 |
---
## 6. 总结
一个 HTTP 请求的完整旅程:
1. **浏览器**:解析 URL → DNS 查询 → TCP 连接 → 发送请求
2. **网络**:路由转发 → CDN 判断 → 负载均衡分发
3. **服务器**:Web 服务器接收 → 中间件处理 → 业务逻辑 → 数据库查询
4. **返回**:构造响应 → 压缩 → 网络传输 → 浏览器渲染
::: tip 理解全链路的价值
当你能在脑中画出请求的完整链路时,遇到任何问题都能快速定位到是哪一层出了问题。这是从"初级开发"到"能独立排查问题"的关键跨越。
:::
---
## 延伸阅读
- [HTTP 权威指南](https://developer.mozilla.org/zh-CN/docs/Web/HTTP) — MDN 的 HTTP 文档
- [High Performance Browser Networking](https://hpbn.co/) — 浏览器网络性能优化
- [What happens when...](https://github.com/alex/what-happens-when) — 经典的"输入 URL 后发生了什么"详解