引言:一次请求要跨越多少道关卡?
当你在浏览器中敲下回车,一个看似简单的 HTTP 请求,实际上要穿越 CDN、WAF、负载均衡、网关、微服务、中间件、数据库 等多达九层的精密协作。理解这条链路,是进行架构设计、性能调优与故障定位的基本功。
本文将以请求的视角,逐层拆解现代服务器架构的核心组件、职责边界与主流技术选型,并给出全链路速查表与排错清单。
flowchart TD
A[用户浏览器 / App] -->|DNS 解析 CNAME| B[CDN 边缘节点]
B -.->|静态命中直接返回| A
B -->|静态未命中,回源| C[WAF Web 应用防火墙]
C -->|进入云 VPC 内网| D[四层负载均衡 SLB / LVS]
D --> E[七层接入网关 ALB / Nginx-Ingress / Higress]
E --> F[API 网关集群]
F --> G[业务微服务集群]
G <-->|服务注册发现| H[Nacos / Eureka]
G --> I[中间件层]
I --> I1[Redis 缓存集群]
I --> I2[Kafka / RocketMQ]
I --> I3[配置中心 Nacos / Apollo]
G --> J[持久化存储层]
J --> J1[MySQL 主从集群]
J --> J2[对象存储 OSS / S3]
J --> J3[Elasticsearch]第一层:CDN 边缘节点 —— 离用户最近的守门员
用户的请求首先通过 DNS 的 CNAME 记录被调度到就近的 CDN 边缘节点。这一层承担着 静态缓存、DDoS 边缘清洗、TLS 卸载与动态加速 四大职责,是抵御流量洪峰的第一道缓冲带。
核心职责
- 静态资源缓存:图片、CSS、JS 等命中后直接返回,==完全不触碰后端链路==。
- DDoS 边缘清洗:利用边缘节点的分布式带宽,在网络边缘吸收流量型攻击。
- TLS 卸载:在边缘节点完成 HTTPS 加解密,减轻源站 CPU 压力。
- 动态加速:对无法缓存的动态请求,通过 BGP 优化链路、专线回源降低时延。
可以通过 dig 命令观察 CNAME 调度过程:
dig www.example.com CNAME +short# 输出示例:# www.example.com.cdn-provider.net.缓存命中率是生命线CDN 的核心 KPI 是 缓存命中率。命中率每下降 10%,回源流量可能翻数倍,源站带宽与计算成本直线上升。建议对静态资源配置合理的
Cache-Control与版本化文件名(如app.a3f8b2.js)实现长效缓存。
第二层:WAF Web 应用防火墙 —— 七层安全的过滤网
穿过 CDN 的回源流量,首先要接受 WAF 的安全审查。WAF 工作在应用层,专门识别业务层面的恶意请求,是进入 VPC 内网前的最后一道安全闸门。
防护能力矩阵
| 攻击类型 | 典型特征 | WAF 处置方式 |
|---|---|---|
| SQL 注入 | ' OR 1=1 --、UNION SELECT | 规则匹配 + 语义分析,直接拦截 |
| XSS 跨站脚本 | <script> 注入、事件处理器 | 特征检测,拦截或转义 |
| CC 攻击 | 单 IP 高频请求动态接口 | 频率限制、人机验证 |
| Bot 爬虫 | 异常 UA、无 Cookie 会话 | 指纹库识别、滑块挑战 |
一条典型的拦截日志如下:
[2024-11-29 14:23:01] BLOCK rule=SQLi-034 src=203.0.113.88uri=/api/user/detail?id=1' UNION SELECT password FROM users--action=deny status=403 upstream=-WAF 不是银弹WAF 基于规则与特征库工作,对 业务逻辑漏洞(如越权访问、条件竞争)无能为力。安全是纵深防御,代码审计与权限校验依然不可替代。
第三层:四层负载均衡(SLB / LVS)—— 连接级别的调度大师
流量进入云 VPC 后,首先到达四层负载均衡器。它工作在 传输层,不关心 HTTP 内容,只负责海量 TCP 连接的建立、调度与健康检查,是抗住大并发连接的基石[^1]。
四层 vs 七层负载均衡对比
| 维度 | 四层(SLB / LVS) | 七层(ALB / Nginx) |
|---|---|---|
| 工作层级 | 传输层(TCP/UDP) | 应用层(HTTP/HTTPS/gRPC) |
| 调度依据 | 源 IP、端口、连接数 | URL、Header、Cookie |
| 性能 | 极高(百万级并发) | 较低(需解析协议) |
| 典型能力 | 连接管理、会话保持、健康检查 | 路由、重写、灰度、限流 |
| 常见实现 | LVS、云厂商 SLB | Nginx、Envoy、云 ALB |
核心机制
- TCP 连接管理:终结或透传客户端连接,屏蔽后端连接抖动。
- 会话调度:支持轮询、最少连接、源地址哈希等算法。
- 健康检查:主动探测后端端口存活,自动摘除异常节点。
第四层:七层接入网关 —— 流量的精细化分拣中心
七层网关是 HTTP 请求的「分拣中心」,负责 证书管理、域名路由、限流、灰度发布与 URL 重写。在云原生体系中,通常由 Nginx-Ingress 或 Higress 承担这一角色。
server { listen 443 ssl; server_name api.example.com;
ssl_certificate /etc/ssl/api.example.com.pem; # TLS 证书托管 ssl_certificate_key /etc/ssl/api.example.com.key;
location /api/v2/ { # 灰度路由: v2 版本流量 proxy_pass http://order-service-v2; proxy_set_header X-Gray-Tag "canary"; }
location /api/ { limit_req zone=api_limit burst=20 nodelay; # 限流 proxy_pass http://api-gateway-cluster; }
rewrite ^/old-path/(.*)$ /api/v1/$1 permanent; # URL 重写}四层与七层为何都要存在?四层 LB 解决的是「连接能不能扛住」,七层网关解决的是「请求该往哪里去」。四层性能强但不理解业务,七层灵活但性能有限,两者是互补而非替代关系。
第五层:API 网关集群 —— 业务流量的统一入口
接入网关之后,请求进入面向业务的 API 网关集群。如果说接入网关管「流量」,API 网关管的就是「接口」:鉴权、签名、熔断、协议转换与日志埋点都在这里完成。
核心能力清单
- 统一鉴权:JWT 校验、OAuth2、AK/SK 签名验证
- 接口级限流:按 API、按用户维度的精细化配额
- 熔断降级:下游服务异常时快速失败,防止雪崩
- 协议转换:对外 RESTful,对内 gRPC/Dubbo
- 日志埋点:统一采集调用链 TraceID,打通可观测性
主流开源方案可参考:
第六层:业务微服务集群 —— 按业务域拆分的计算核心
通过 API 网关校验后的请求,最终抵达业务微服务集群。服务按 业务域 拆分(用户、订单、商品、支付……),以 Pod 或 ECS 实例形态部署,通过注册中心完成服务发现。
服务注册与发现
spring: cloud: nacos: discovery: server-addr: nacos-cluster:8848 # 注册中心地址 namespace: prod group: order-group # 订单域分组 application: name: order-service- 服务启动时向 Nacos / Eureka 注册自身实例信息。
- 调用方通过注册中心获取可用实例列表,配合客户端负载均衡发起调用。
- 实例心跳中断后自动下线,实现故障实例的秒级摘除。
拆分的度微服务不是拆得越细越好。一个经验法则:==服务边界应与团队边界对齐==(康威定律)。过细的拆分会让分布式事务、调用链复杂度急剧上升。
第七层:中间件层 —— 性能与解耦的加速器
微服务并非直接访问数据库,而是先经过中间件层的缓冲与解耦。这一层是系统高并发能力的决定性因素。
三剑客分工
| 中间件 | 代表产品 | 核心场景 |
|---|---|---|
| 缓存 | Redis 集群 | 热点数据、用户会话、分布式计数器 |
| 消息队列 | Kafka / RocketMQ | 异步削峰、业务解耦、事件驱动 |
| 配置中心 | Nacos / Apollo | 配置热更新、多环境管理 |
典型场景:缓存旁路模式(Cache-Aside)
public Order getOrder(String orderId) { // 1. 先查缓存 Order cached = redisClient.get("order:" + orderId); if (cached != null) { return cached; // 缓存命中,直接返回 } // 2. 缓存未命中,回源数据库 Order order = orderMapper.selectById(orderId); if (order != null) { // 3. 回写缓存,设置过期时间防止雪崩 redisClient.setex("order:" + orderId, 300 + jitter(), order); } return order;}典型场景:消息队列削峰
秒杀下单时,服务不直接写库,而是投递消息到 RocketMQ,由消费者匀速处理:
# 秒杀瞬间: 峰值 50w QPS 打入 MQ[PRODUCER] send order_create_msg topic=seckill_order cost=2ms ✔# 消费者以 5w QPS 匀速消费,数据库平稳无压力[CONSUMER] consume batch=32 lag=120000 tps=50000缓存三大经典问题穿透(查询不存在的数据)、击穿(热点 Key 过期瞬间被打爆)、雪崩(大量 Key 同时过期)。上例中的随机过期时间
jitter()就是针对雪崩的防御手段,实际生产还需配合布隆过滤器与互斥锁。
第八层:持久化存储层 —— 数据的最终归宿
所有计算与缓存的尽头,是持久化存储。现代架构按数据特征选择不同的存储引擎,而非一套 MySQL 打天下。
存储选型速查
| 存储类型 | 代表产品 | 存放数据 | 读写特征 |
|---|---|---|---|
| 关系型数据库 | MySQL 主从集群 | 订单、用户等强一致性业务数据 | 主库写、从库读,读写分离 |
| 对象存储 | OSS / S3 | 图片、视频、附件等非结构化文件 | 海量、低成本、CDN 回源 |
| 搜索引擎 | Elasticsearch | 商品检索、日志分析 | 近实时检索、复杂聚合 |
读写分离的代价主从复制存在 毫秒到秒级延迟。对于「写完立刻读」的场景(如下单后查看订单),需要强制走主库或采用半同步复制,避免出现「刚付完款却查不到订单」的诡异现象。数据库真实内网地址形如
10.0.3.17:3306 ,应严格限制在 VPC 内网可达。
返回链路:应答如何回到用户手中
请求抵达存储层并完成处理后,应答将 沿原路逐层返回:微服务 → API 网关 → 接入网关 → 四层 LB → CDN → 用户。
但返回链路并非完全对称,有两个关键细节:
- 静态命中短路:若响应在 CDN 边缘命中缓存,链路在第一步就已终止,后续所有层级的流量为零——这正是 CDN 的价值所在。
- 逐层追加治理信息:返回途中各层会附加自己的处理逻辑,如网关补充响应头、CDN 写入缓存、WAF 记录审计日志。
flowchart LR
S[存储层] --> M[中间件/微服务] --> G[API 网关] --> I[接入网关]
I --> L[四层 LB] --> W[WAF] --> C[CDN] --> U[用户]
C -.->|静态响应| U全链路职责速查表
一张表回顾整条链路的分层职责:
| 层级 | 组件 | 核心职责 | 一句话记忆 |
|---|---|---|---|
| 边缘层 | CDN | 静态缓存、DDoS 清洗、TLS 卸载 | 能拦在门外的,绝不放进来 |
| 安全层 | WAF | 七层攻击过滤 | 恶意请求的最后筛查 |
| 接入层 | SLB / LVS | TCP 连接调度、健康检查 | 扛住连接洪峰 |
| 路由层 | ALB / Ingress | 证书、路由、灰度、限流 | 流量的分拣中心 |
| 接口层 | API 网关 | 鉴权、熔断、协议转换 | 接口的统一门面 |
| 计算层 | 微服务集群 | 业务逻辑处理 | 按域拆分、注册发现 |
| 加速层 | Redis / MQ / 配置中心 | 缓存、削峰、解耦 | 性能的倍增器 |
| 存储层 | MySQL / OSS / ES | 数据持久化 | 按数据特征选型 |
常见故障定位清单
线上请求异常时,建议 沿链路自外向内逐层排查:
- CDN:缓存命中率是否骤降?边缘节点是否故障?
- WAF:是否存在误拦截(检查拦截日志与规则命中)?
- SLB:健康检查是否大面积异常摘除后端?
- 接入网关:是否正常路由流量?