Skip to content

一个請求的完整旅程

前言

当你在浏览器裡輸入一个網址按下回車,到頁面顯示出來,中間到底發生了什么? 這个問题是面試經典题,更是理解整个 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 解析渲染

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 → 根域名服務器
     ↓ 命中就直接用,不命中就往下查

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 }

數據庫是最常见的性能瓶颈

網絡傳輸通常是毫秒级,應用邏輯也很快,但一个没有索引的數據庫查询可能要几秒甚至几十秒。所以"慢請求"大概率是數據庫查询慢。


4. 響應返回:數據的归途

4.1 構造 HTTP 響應

服務器處理完後,構造響應报文:

http
HTTP/1.1 200 OK
Content-Type: application/json
Content-Encoding: gzip
Cache-Control: max-age=3600

{"id": 123, "title": "xxx", "price": 59.9}
組成部分內容
狀態行協议版本 + 狀態碼(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. 绘制 → 把像素画到屏幕上

5. 全鏈路優化:每一層都能更快

5.1 各層優化手段

層级優化手段效果
DNSDNS 预解析、使用快速 DNS 服務减少 DNS 查询時間
網絡CDN、HTTP/2、連接複用减少傳輸延遲
服務器緩存(Redis)、异步處理减少處理時間
數據庫索引、查询優化、讀写分離减少查询時間
前端懒加載、代碼分割、资源压缩减少渲染時間

5.2 緩存:最有效的優化

緩存存在于請求鏈路的每一層:

浏览器緩存 → CDN 緩存 → 反向代理緩存 → 應用緩存(Redis)→ 數據庫緩存

緩存的本质

用空間换時間。把計算過的結果存起來,下次直接用,不用重新算。緩存命中率每提高 10%,系统性能可能提升數倍。

5.3 請求失敗時的排查思路

現象可能的問题層排查方法
完全无響應DNS / 網絡ping、nslookup
連接超時網絡 / 服務器宕機telnet、curl
返回 4xx客户端請求有误檢查 URL、參數、Token
返回 5xx服務器內部錯误查看服務器日志
響應很慢數據庫 / 應用邏輯查看慢查询日志、APM 工具

6. 總結

一个 HTTP 請求的完整旅程:

  1. 浏览器:解析 URL → DNS 查询 → TCP 連接 → 發送請求
  2. 網絡:路由轉發 → CDN 判断 → 负載均衡分發
  3. 服務器:Web 服務器接收 → 中間件處理 → 業務邏輯 → 數據庫查询
  4. 返回:構造響應 → 压缩 → 網絡傳輸 → 浏览器渲染

理解全鏈路的价值

当你能在脑中画出請求的完整鏈路時,遇到任何問题都能快速定位到是哪一層出了問题。這是從"初级開發"到"能独立排查問题"的關鍵跨越。


延伸阅讀