预计时间
2 周
学习目标
- 理解 CDN → Gateway → LB → Service → Cache → MQ → DB 全链路
- 掌握 QPS / 存储 / 带宽估算方法
- 能独立设计中型 SaaS 架构
- 理解微服务拆分原则
一、全链路架构总览
text
用户请求
↓
┌─── CDN ───┐
│ 静态资源 │
│ DNS 解析 │
└───────────┘
↓
DNS / GSLB
↓
┌── Gateway ──┐
│ 统一入口 │
│ 鉴权 / 限流 │
│ 路由 / 日志 │
└─────────────┘
↓
┌─ Load Balancer ─┐
│ 流量分发 │
│ 健康检查 │
└─────────────────┘
↓ ↓ ↓
Service Service Service
↓ ↓ ↓
┌── Cache (Redis) ─┐
│ 热点数据 │
└──────────────────┘
↓
┌─ Message Queue ─┐
│ 异步任务 │
└─────────────────┘
↓
┌── Database ──┐
│ PostgreSQL │
│ Vector DB │
└──────────────┘二、逐层拆解
2.1 CDN(内容分发网络)
text
没有 CDN:
北京用户访问深圳服务器 → 延迟 50ms
纽约用户访问深圳服务器 → 延迟 300ms
所有用户都打同一台服务器
有 CDN:
北京用户 → 北京节点(5ms)
纽约用户 → 纽约节点(5ms)
源站压力降低 90%+CDN 缓存什么?
- 静态资源:JS、CSS、图片、字体
- 不缓存:API 响应、用户数据
关键参数:Cache-Control 头
text
Cache-Control: public, max-age=31536000, immutable
→ 告诉 CDN:这个文件一年不变,放心缓存2.2 API Gateway(网关)
职责:
text
1. 统一入口 — 不是每个服务暴露一个公网 IP
2. 认证鉴权 — JWT 验证、API Key 校验,在网关层解决
3. 限流 — 防止某个客户端把服务打挂
4. 路由 — /api/users → user-service, /api/docs → doc-service
5. 日志 — 统一记录请求日志
6. 协议转换 — 外部 REST → 内部 gRPC常见选型:
- Kong(功能全,插件多)
- Nginx + Lua(高性能,灵活)
- Traefik(云原生,自动发现)
- 云厂商:AWS API Gateway、阿里云 API Gateway
2.3 Load Balancer(负载均衡)
text
LB
/ | \
Svr1 Svr2 Svr3
策略:
轮询 (Round Robin) — 轮流分配,最常用
最少连接 — 谁空闲给谁
IP Hash — 同一用户固定到同一服务器(会话保持)
健康检查:
LB 每 5 秒 GET /health → 200 OK 就是活着 → 不响应的摘掉2.4 Cache(缓存)
text
多级缓存架构:
L1: 浏览器缓存(Cache-Control, ETag)
L2: CDN 缓存
L3: 应用层本地缓存(内存、LRU)
L4: Redis 分布式缓存
L5: 数据库 Buffer Pool
命中 L1 → 0ms(不发起网络请求)
命中 L2 → ~5ms
命中 L4 → ~1ms
命中 L5 → ~5ms
穿透到磁盘 → ~10ms2.5 Message Queue(消息队列)
text
作用:解耦 + 削峰 + 异步
典型场景:
用户注册 → 发验证邮件(无需同步等待)
订单创建 → 扣库存 → 发短信 → 写日志(一串异步任务)
数据同步 → Binlog → Kafka → 搜索引擎 / 数据仓库2.6 Database
text
读写分离:
Master(写) → 同步 → Slave1, Slave2(读)
写走 Master,读走 Slave
分库分表:
水平拆分:用户表按 user_id % 4 分到 4 个库
垂直拆分:用户库、订单库、商品库
什么时候需要?
单表 > 1000万行、单库 QPS > 1000 → 考虑拆分三、设计方法论
3.1 从需求到架构
text
Step 1: 理需求
- 这是做什么的系统?
- 用户是谁?有多少?
- 核心功能是什么?
Step 2: 估规模
- 日活 (DAU) 多少?
- 每人每天多少次请求?
- QPS = DAU × 平均请求数 / 86400 × 峰值系数
Step 3: 算存储
- 每条数据多大?
- 每天产生多少数据?
- 1 年 = 日增量 × 365 × 副本数
Step 4: 画架构图
- 先画数据流:请求从哪里来,到哪里去
- 再加组件:哪里需要缓存、哪里需要 MQ、哪里需要 LB
Step 5: 选技术
- 数据库:关系型 or NoSQL?
- 缓存:Redis or Memcached?
- MQ:Kafka or RabbitMQ?3.2 估算示例:AI 知识库 SaaS
text
假设:
- 1000 个企业客户
- 平均每企业 50 个用户 = 50,000 用户
- 日活 20% = 10,000 人
- 每人每天 20 次问答
QPS:
10,000 × 20 / 86400 ≈ 2.3 QPS (平均)
峰值 × 5 ≈ 12 QPS
→ 很小,单体架构完全够
存储:
每企业平均 1000 个文档
每文档平均 500KB = 500MB / 企业
1000 企业 × 500MB = 500GB
+ 向量数据 (每 chunk 1536 维 ≈ 6KB)
每文档 50 个 chunk × 6KB = 300KB
1000 企业 × 1000 文档 × 300KB = 300GB
→ 总计约 1TB(一年),单机 PostgreSQL + pgvector 轻松扛
结论:
不需要微服务、不需要分库分表、不需要 Kafka
→ NestJS + PostgreSQL + Redis 单体架构足够
→ 等客户到 10,000 再考虑拆分
记住:架构是演进的,不是一步到位的。四、微服务拆分
4.1 什么时候拆?
text
✅ 该拆的信号:
- 一个团队改代码,另一个团队不敢上线
- 某个模块需要独立扩容(搜索服务需要更多机器)
- 不同模块需要不同技术栈(Python ML + Node.js API)
- 部署频率不同(核心业务一个月发一次,推荐引擎每天发)
❌ 不该拆:
- "微服务是潮流"——不是
- 团队只有 3 个人——拆了维护成本翻倍
- 系统 QPS < 100——单体够用4.2 怎么拆?
text
按领域拆分(DDD)而不是按技术层:
❌ 按技术层:Controller 服务 → Service 服务 → DAO 服务
→ 每个请求跨 3 个服务,延迟翻倍
✅ 按领域:用户服务、文档服务、搜索服务、计费服务
→ 一个请求通常只涉及 1-2 个服务五、AI 客服系统设计实战
需求
text
企业客服系统,支持:
- 用户通过 Web/API 提问
- 基于企业知识库的 RAG 问答
- 支持人工转接
- 支持多租户
- SLA:99.9%,P99 延迟 < 2s架构设计
text
Client (Web / API)
↓
CDN (静态资源)
↓
API Gateway (Kong)
├─ 限流:每租户 100 QPS
├─ 鉴权:JWT + API Key
└─ 路由:/chat → chat-service
↓
Chat Service (NestJS × 3)
├─ 接收问题
├─ 查缓存(Redis):相同问题 10 分钟内直接返回
├─ 调 RAG Service
└─ 调 LLM
↓
RAG Service
├─ Embedding 检索 (Vector DB)
├─ Rerank (精排)
└─ Prompt 拼接
↓
LLM (OpenAI / Claude)
↓
MQ (Kafka) ← 日志、监控、计费
↓
PostgreSQL ← 会话记录、用户、计费技术选型理由
| 组件 | 选型 | 理由 |
|---|---|---|
| Gateway | Kong | 插件丰富,限流/鉴权开箱即用 |
| 应用 | NestJS | 前端背景友好,TypeScript |
| 缓存 | Redis | 会话缓存 + Prompt 缓存 + 限流计数器 |
| MQ | Kafka | 日志量大、需要保留审计 |
| 数据库 | PostgreSQL + pgvector | 简化架构,不需要独立的 Vector DB |
| LLM | OpenAI / Claude | 质量最好,Function Calling 成熟 |
推荐资源
- System Design Primer (GitHub) — 必读
- 《Designing Data-Intensive Applications》— 系统设计圣经
- B 站搜"秒杀系统设计""高并发架构"
实践
- 选一个你常用的 App(微信 / 淘宝 / B站),尝试画出它的架构图
- 估算:日活 10 万,每人每天 50 次请求 → QPS 多少?需要几台服务器?
- 设计一个简单的 SaaS 系统(比如在线表单),从 CDN 到 DB 画全链路