02 - 全链路瓶颈地图
上一章讲了优化的两个方向。这一章我们把「一个请求的完整旅程」画出来,标出每一层可能出现的瓶颈,以及对应的优化手段。
这张地图是本教程的「总纲」——后面每一章,其实都是在讲这张图上某一层的优化。
一句话先记住:优化不是玄学,而是「顺着请求的路径,一层一层找瓶颈」。
2.1 一个请求的完整旅程
用户
│ ①
▼
┌─────────────┐
│ CDN / 静态 │ ② 图片、JS、CSS 等静态资源
└──────┬──────┘
│ ③
▼
┌─────────────┐
│ 网关 / Nginx │ ④ 反向代理、负载均衡、限流
└──────┬──────┘
│ ⑤ 分发到多台
▼
┌─────────────┐
│ 应用服务 │ ⑥ FastAPI 业务逻辑、并发模型
│ (FastAPI) │
└──────┬──────┘
│ ⑦
├──────────────┐
▼ ▼
┌───────────┐ ┌───────────┐
│ 缓存 Redis │ │ 消息队列 │ ⑧ 异步任务
└─────┬─────┘ └───────────┘
│ ⑨ 缓存没命中才查库
▼
┌───────────┐
│ PostgreSQL │ ⑩ 数据库:最容易成为瓶颈的一层
└───────────┘
2.2 每一层的瓶颈与对策
| 层次 | 常见瓶颈 | 对应优化手段 | 对应章节 |
|---|---|---|---|
| ① 客户端 / 网络 | 请求太多、传输慢 | CDN、静态资源分离、压缩 | 本章 |
| ④ 网关层 | 恶意/突发流量打进来 | 限流、负载均衡 | 06、07 |
| ⑥ 应用层 | 单机连接数上限、CPU 密集 | 异步 IO、并发模型、水平扩展 | 05、08 |
| ⑦ 应用↔下游 | 频繁创建连接开销大 | 连接池、线程/协程池 | 05 |
| ⑧ 慢任务 | 发邮件、生成报表拖慢主流程 | 异步化、消息队列削峰 | 04 |
| ⑨ 缓存层 | 缓存击穿/穿透/雪崩 | 多级缓存、缓存保护 | 03 |
| ⑩ 数据库层 | 慢查询、连接数打满、单表过大 | 索引、读写分离、分库分表 | 06 + 系列三 |
关键认知:越往下(越靠近数据库),资源越稀缺、越慢、越难扩展。所以优化的一个核心思想是——尽量在上层就把请求「拦下来」,别让它一路打到数据库。
2.3 优化的「拦截」思想
这是高并发架构最重要的直觉。想象请求像水流,我们在每一层都设一道「闸门」,能拦就拦,能少一个是一个:
10000 请求
│
▼
[CDN] → 拦掉 3000(静态资源直接返回)
│ 7000
▼
[网关限流] → 拦掉 1000(超出容量的直接拒绝)
│ 6000
▼
[本地缓存] → 拦掉 2000(进程内热点数据)
│ 4000
▼
[Redis 缓存] → 拦掉 3500(绝大多数读请求)
│ 500
▼
[数据库] → 只剩 500 真正需要查库的
一开始 10000 个请求,层层过滤后,真正打到数据库的只剩 500 个。数据库自然就扛得住了。
这就是高并发的核心套路:让越昂贵、越慢的资源(数据库),承担越少的请求。
2.4 怎么用这张地图
遇到性能问题时,按这个顺序自问:
1. 是静态资源慢吗? → 上 CDN
2. 是流量太大打崩了吗? → 网关限流 + 加机器
3. 是应用算不过来吗? → 看是 IO 密集还是 CPU 密集,选并发模型 / 水平扩展
4. 是有慢任务拖累吗? → 异步化,丢消息队列
5. 是读请求太多吗? → 加缓存 / 读写分离
6. 是数据库本身慢吗? → 索引优化,实在不行分库分表
后面的章节,就是把这 6 步逐一讲透。
本章小结
| 你要记住 | 要点 |
|---|---|
| 请求旅程 | 客户端 → CDN → 网关 → 应用 → 缓存 → 数据库 |
| 瓶颈规律 | 越靠近数据库越稀缺、越慢、越难扩展 |
| 拦截思想 | 每一层能拦就拦,别让请求一路打到数据库 |
| 排查顺序 | 顺着链路从上到下,一层层找瓶颈 |
下一章预告:拦截请求最有效的一招——缓存。它是高并发的第一利器,我们从多级缓存讲到「缓存三大坑」。
上一章 ← 01 - 什么是高并发 | 下一章 → 03 - 缓存:高并发第一利器