Skip to content

网关与反向代理

🎯 核心问题

在高并发的互联网架构中,如何把流量安全、高效地送到正确的服务? 反向代理解决"流量怎么分发",API网关解决"请求怎么处理"。本文通过真实案例(前台接待、保安系统、智能路由)深入理解网关的设计哲学和工程实践。


1. 为什么要"网关"?

1.1 从一个真实案例说起:某电商的架构演进

某电商平台在业务快速增长时遇到了严重的架构问题:

场景还原:

阶段一:直接暴露服务
客户端 → 直接调用用户服务、订单服务、支付服务...

问题1:服务IP暴露,存在安全隐患
问题2:无法统一做认证、限流
问题3:新增服务需要修改客户端配置

⚠️ 直接暴露的致命问题

  • 安全隐患: 所有服务IP暴露,容易被攻击
  • 功能重复: 每个服务都要做认证、限流、日志
  • 扩展困难: 新增服务要修改所有客户端
  • 协议混乱: 有的用HTTP,有的用gRPC,客户端要适配

改进后的架构(引入网关):

客户端 → API网关(Nginx/Kong) → 内部服务

      统一认证、限流、路由

      客户端只知道网关地址

✨ 改进后的效果

  • 安全: 真实服务IP隐藏,只有网关对外
  • 功能收敛: 认证、限流、日志在网关统一处理
  • 扩展容易: 新增服务只需网关配置路由
  • 协议统一: 对外HTTP,内部可用gRPC

1.2 网关的生活化比喻

前台接待

想象你去一家大公司:

  • 没有前台: 访客直接找各部门,不知道在哪,公司乱成一团
  • 有前台: 访客先到前台,前台问清楚来意,再引导到对应部门

API网关就是系统的"前台":

  • 反向代理: 前台,引导访客到正确的部门
  • API网关: 智能前台,还能检查访客身份(认证)、限制访问人数(限流)
🔄 反向代理 vs 正向代理
一句话区分:正向代理是"客户端的代理",反向代理是"服务器的代理"
👤
用户 (浏览器)
访问域名
🛡️
反向代理 (Nginx)
代理服务器
负载均衡
⚙️
后端服务器集群
Web1 | Web2 | Web3
🛡️ 反向代理特点
  • 客户端无感知,只需要访问域名
  • 隐藏真实服务器架构,统一对外接口
  • 提供负载均衡、安全防护、SSL卸载等功能
  • 典型代表:Nginx、HAProxy、AWS ELB
💡 典型使用场景
  • 网站需要承载高并发流量(负载均衡)
  • 统一HTTPS证书管理(SSL卸载)
  • 防护DDoS攻击和SQL注入
  • 灰度发布、A/B测试、蓝绿部署
🧠 记忆口诀

"反向代理 = 代理服务器" —— 客户端不知道真实服务器,只知道域名


2. 什么是反向代理?

2.1 正向代理 vs 反向代理

🤔 术语解释

正向代理(Forward Proxy):

  • 部署在客户端侧
  • 代替客户端访问外部资源
  • 典型应用:VPN、翻墙工具
  • 例子:公司网络,你通过代理访问外网

反向代理(Reverse Proxy):

  • 部署在服务器端
  • 接收客户端请求并转发给内部服务
  • 客户端只知道代理存在,不知道真实服务器
  • 例子:Nginx、HAProxy

对比表:

维度正向代理反向代理
部署位置客户端侧服务器端
服务对象客户端服务器
典型应用VPN、翻墙负载均衡、网关
透明性服务器看到代理IP客户端看到代理IP
目的隐藏真实客户端、加速访问隐藏真实服务器、负载均衡

2.2 反向代理的核心价值

价值一:负载均衡

将流量分发到多个后端服务器,避免单点过载。

客户端

Nginx(反向代理)

┌─────────┬─────────┬─────────┐
│ 服务器1 │ 服务器2 │ 服务器3 │
└─────────┴─────────┴─────────┘
价值二:安全防护

隐藏真实服务器IP,防止直接攻击。统一在代理层做安全防护。

客户端 → 只能看到Nginx的IP
真实服务器 → 只在内网,外部无法直接访问
价值三:SSL终结

在代理层处理HTTPS加密解密,后端服务用HTTP,降低后端计算开销。

HTTPS客户端 → Nginx(加密/解密) → HTTP后端服务

              SSL终结点

3. Nginx:为什么能扛起百万并发?

3.1 Master-Worker进程模型

Nginx采用多进程架构,而不是多线程:

Master进程(管理者):

  • 负责读取和验证配置文件
  • 管理Worker进程(启动、停止、重新加载)
  • 不处理具体请求

Worker进程(工作者):

  • 实际处理HTTP请求
  • 每个Worker是独立的进程,相互隔离
  • 数量通常设置为CPU核心数,避免上下文切换开销

💡 优势

  • 隔离性好: 一个Worker崩溃,不影响其他Worker
  • 充分利用多核: 每个Worker独立运行
  • 避免多线程复杂性: 无需处理锁、竞争等问题

3.2 事件驱动 + 异步非阻塞

这是Nginx高性能的核心秘密:

传统Apache(多进程/线程模型):

  • 一个连接 = 一个进程/线程
  • 并发数受限于系统进程/线程数
  • 大量连接时,进程切换开销巨大

Nginx(事件驱动模型):

  • 使用epoll(Linux)/kqueue(macOS)等高效I/O多路复用机制
  • 一个Worker进程可以同时处理数万个连接
  • 连接没有数据时,不会占用CPU,有新数据时通过事件通知唤醒

生活化比喻

  • Apache: 餐厅里每个顾客配一个服务员(进程),顾客多需要大量服务员
  • Nginx: 一个超级服务员,同时服务所有顾客,谁需要服务就去谁那里,而不是一直站在某个顾客旁边
⚡ Nginx 架构揭秘:为什么它能扛住百万并发?
Master-Worker 进程模型 + 事件驱动 = 高性能的秘诀
Nginx 进程架构图
👑
Master 进程
管理所有 Worker,负责配置加载、平滑升级
4 个 Worker
⚙️
Worker 1
处理 0 请求
⚙️
Worker 2
处理 0 请求
⚙️
Worker 3
处理 0 请求
⚙️
Worker 4
处理 0 请求
📡 epoll (Linux) / kqueue (macOS)
事件驱动:一个 Worker 同时处理数万个连接
传统 Apache
一个连接 = 一个进程/线程
❌ C10K 问题
VS
Nginx
事件驱动 + 异步非阻塞
✅ 百万并发
🎮 模拟请求处理
💡 生产环境建议
Worker 数量 = CPU 核心数(通常设置为 auto,让 Nginx 自动检测)
太多了上下文切换开销大,太少了无法利用多核性能。

4. 什么是API网关?

4.1 为什么需要API网关?

想象一个没有网关的系统:

  • 客户端需要知道多个服务的地址(用户服务、订单服务、支付服务...)
  • 每个服务都要自己做认证、限流、日志
  • 协议不统一,有的用HTTP,有的用gRPC
  • 服务升级时,客户端也需要跟着改

⚠️ 没有网关的问题

  • 客户端复杂: 需要配置多个服务地址
  • 功能重复: 每个服务都要实现认证、限流
  • 协议混乱: 客户端要适配多种协议
  • 升级困难: 服务升级,客户端也要改

有了API网关之后:

  • 客户端只需要知道网关地址,网关负责路由到正确服务
  • 认证、限流、日志等横切逻辑统一在网关处理
  • 网关可以做协议转换,对外统一暴露HTTP
  • 后端服务升级,只需要改网关配置,客户端无感知
🚪 API 网关:系统的"统一大门"
想象成写字楼的「前台」——所有访客都要先经过这里,才能到达不同的办公室
客户端 (来访者)
📱 App
💻 Web
🔧 第三方
⬇️ 统一入口
🚪 API 网关 (前台)
🔐身份认证
限流熔断
🧭路由转发
🔄协议转换
⬇️ 分发请求
⚙️ 后端服务 (各个部门)
👤
用户服务
/api/users
📦
订单服务
/api/orders
💳
支付服务
/api/pay
🔐身份认证
统一校验用户身份,无需每个后端服务都写登录逻辑。支持 JWT、OAuth2、API Key 等多种认证方式。
💡 实际场景
用户请求携带 JWT Token,网关校验签名和过期时间,通过后把用户ID添加到请求头转发给后端服务。
🤔 没有网关 vs 有网关的区别
功能需求没有网关 (直接访问)有 API 网关
身份认证每个服务都要写一遍登录校验✅ 统一在网关层校验 JWT
限流保护每个服务自己实现限流✅ 网关统一限流,保护后端
协议转换HTTP、gRPC、WebSocket各自处理✅ 网关统一对外暴露 HTTP
灰度发布需要改负载均衡器配置✅ 网关层按 Header 路由

4.2 API网关的核心功能

功能说明典型场景
路由转发根据URL、Header等规则,将请求转发到不同服务/api/users → 用户服务,/api/orders → 订单服务
负载均衡同一个服务有多实例时,分摊流量用户服务有3台实例,轮询分发请求
认证鉴权统一校验JWT、OAuth Token未登录用户无法访问/api/admin
限流熔断控制流量上限,防止服务被压垮每秒最多1000请求,超过返回429
协议转换对外HTTP,内部可转gRPC客户端用HTTP,网关转gRPC调用内部服务
灰度发布按Header或比例,将部分流量导到新版本5%用户体验新版本,95%用旧版本
日志监控统一记录请求日志,便于分析和排障记录每次请求的耗时、状态码、返回大小

5. 网关实战:如何构建完整的网关架构?

5.1 完整架构图

┌───────────────────────────────────────────────────────────────────────┐
│                           客户端(浏览器/APP)                               │
└───────────────────────────┬─────────────────────────────────────────┘
                                │ HTTPS

┌───────────────────────────────────────────────────────────────────────┐
│                        外层:CDN + WAF                                  │
│  ┌─────────────────────────────────────────────────────────────┐  │
│  │  CDN(内容分发网络)                                        │  │
│  │  - 静态资源缓存(图片、CSS、JS)                           │  │
│  │  - 就近访问,降低延迟                                   │  │
│  └───────────────────────────────────────────────────────────────┘  │
│  ┌───────────────────────────────────────────────────────────────┐  │
│  │  WAF(Web应用防火墙)                                     │  │
│  │  - 防护SQL注入、XSS攻击                                │  │
│  │  - 拦截恶意Bot、爬虫                                  │  │
│  │  - CC攻击防护                              │  │
│  └───────────────────────────────────────────────────────────────┘  │
└───────────────────────────────────────────────────────────────────────┘


┌───────────────────────────────────────────────────────────────────────┐
│                     中层:API网关(Nginx/Kong)                      │
│  ┌───────────────────────────────────────────────────────────────┐  │
│  │  第一层:SSL终结 + 安全防护                              │  │
│  │  - HTTPS / TLS 1.3                                        │  │
│  │  - HSTS、安全响应头                                        │  │
│  └───────────────────────────────────────────────────────────────┘  │
│  ┌───────────────────────────────────────────────────────────────┐  │
│  │  第二层:认证与鉴权                                      │  │
│  │  - JWT Token校验                                         │  │
│  │  - OAuth 2.0 / SSO集成                                     │  │
│  │  - API Key管理                                         │  │
│  │  - 权限校验(RBAC)                                        │  │
│  └───────────────────────────────────────────────────────────────┘  │
│  ┌───────────────────────────────────────────────────────────────┐  │
│  │  第三层:流量控制                                        │  │
│  │  - 限流- 令牌桶/漏桶算法                             │  │
│  │  - 熔断- 防止故障扩散                                 │  │
│  │  - 降级- 服务不可用时的备用方案                         │  │
│  │  - 灰度发布- 按比例分配流量                          │  │
│  └───────────────────────────────────────────────────────────────┘  │
│  ┌───────────────────────────────────────────────────────────────┐  │
│  │  第四层:路由与负载均衡                                    │  │
│  │  - 路径路由- Path-based Routing)                          │  │
│  │  - 域名路由- Host-based Routing)                           │  │
│  │  - Header路由- Header-based Routing)                             │  │
│  │  - 负载均衡算法- 轮询/加权/最少连接/IP哈希)             │  │
│  │  - 服务发现- Service Discovery)集成                        │  │
│  └───────────────────────────────────────────────────────────────┘  │
│  ┌───────────────────────────────────────────────────────────────┐  │
│  │  第五层:协议转换与数据处理                                 │  │
│  │  - SSL终结- HTTPS ↔ HTTP)                                   │  │
│  │  - 协议转换- HTTP ↔ gRPC / WebSocket)                         │  │
│  │  - 请求/响应转换- JSON ↔ XML)                               │  │
│  │  - 数据压缩- Gzip / Brotli)                                   │  │
│  │  - 缓存- Cache)- 静态资源和API响应                          │  │
│  └───────────────────────────────────────────────────────────────┘  │
└───────────────────────────────────────────────────────────────────────┘


┌───────────────────────────────────────────────────────────────────────┐
│                        内层:微服务集群                             │
│  ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐      │
│  │  用户服务    │ │  订单服务    │ │  商品服务    │ │  支付服务    │      │
│  │  User Svc   │ │  Order Svc  │ │ Product Svc │ │ Payment Svc │      │
│  │             │ │             │ │             │ │             │      │
│  └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘      │
│         │                │                │                │               │
│         └────────────────┴────────────────┴────────────────┘               │
│                                       │                              │
│                    服务发现与配置中心/ etcd)                          │
│                    - 服务注册与发现                                      │
│                    - 健康检查                                              │
│                    - KV配置存储                                              │
└───────────────────────────────────────────────────────────────────────┘

5.2 路由与负载均衡

网关的核心职责之一,就是把请求送到正确的地方。这涉及两个关键能力:路由(去哪台服务器)和负载均衡(怎么分配流量)。

路由规则:从URL到服务

想象一个电商系统,不同的URL对应不同的服务:

  • /api/users/* → 用户服务
  • /api/orders/* → 订单服务
  • /api/products/* → 商品服务
  • /api/pay/* → 支付服务

Nginx配置示例:

nginx
server {
    listen 80;
    server_name api.example.com;

    # 用户服务
    location /api/users/ {
        proxy_pass http://user-service;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    # 订单服务
    location /api/orders/ {
        proxy_pass http://order-service;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    # 商品服务
    location /api/products/ {
        proxy_pass http://product-service;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    # 支付服务(需要更高安全级别)
    location /api/pay/ {
        # 限制IP访问
        allow 10.0.0.0/8;
        deny all;

        proxy_pass http://payment-service;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
负载均衡:四种策略对比

当同一个服务有多个实例时,如何选择?

策略原理适用场景优点缺点
轮询按顺序依次分配给每台服务器服务器性能相近简单公平不考虑服务器当前负载
加权轮询按权重比例分配,权重高的分配更多服务器性能不均充分利用高性能服务器需要合理设置权重
最少连接分配给当前连接数最少的服务器长连接场景、视频流动态适应负载变化需要实时统计连接数
IP哈希根据客户端IP计算哈希,同一IP永远分配到同一台服务器需要会话保持保证会话一致性某个IP流量大时会造成单点压力

Nginx配置示例:

nginx
# 加权轮询
upstream backend_weighted {
    server 10.0.1.10:8080 weight=3;  # 性能好,承担更多流量
    server 10.0.1.11:8080 weight=2;
    server 10.0.1.12:8080 weight=1;  # 性能差,承担较少流量
}

# 最少连接
upstream backend_least_conn {
    least_conn;
    server 10.0.1.10:8080;
    server 10.0.1.11:8080;
    server 10.0.1.12:8080;
}

# IP哈希(会话保持)
upstream backend_ip_hash {
    ip_hash;
    server 10.0.1.10:8080;
    server 10.0.1.11:8080;
    server 10.0.1.12:8080;
}
⚖️ 负载均衡:把"压力"均匀分摊到多台服务器
想象成银行的取号系统——把客户均匀分配到各个窗口,避免某个窗口排长队
选择负载均衡策略
🎮 负载均衡模拟器
💡
轮询 - 挨个分发,雨露均沾
按照服务器列表的顺序,依次将请求分配给每台服务器。就像银行叫号,1号窗口完事了到2号,2号完事了到3号,轮着来。
🏢 后端服务器集群
4 台
🖥️
Server-A
11%
请求数:0
权重:5
最近请求:
🖥️
Server-B
20%
请求数:0
权重:5
最近请求:
🖥️
Server-C
39%
请求数:0
权重:2
最近请求:
🖥️
Server-D
40%
请求数:0
权重:1
最近请求:
📨 请求队列
总请求: 0待处理: 0
📊 负载分布统计
28%
平均负载
40%
最高负载
12.4
负载标准差
Server-D
最忙服务器

6. 网关安全:如何守护系统大门?

6.1 认证与鉴权

传统方式(每个服务各自认证):

  • 用户服务、订单服务、支付服务...每个都要校验JWT
  • 代码重复,维护困难
  • secret分散在各个服务,泄露风险高

网关统一认证:

  • 客户端携带Token访问网关
  • 网关校验Token合法性(签名、过期时间)
  • 校验通过后,将用户信息(如user_id)添加到请求头,转发给后端服务
  • 后端服务无需校验,直接从Header获取用户信息

💡 核心思想

认证在网关,鉴权在服务:

  • 认证: 你是谁?(校验Token,获取用户身份)
  • 鉴权: 你能做什么?(根据用户角色判断权限)

就像公司前台:前台认证你的身份(身份证),但具体权限由各部门判断。

🔐 认证中间件:谁可以进大门?
想象成写字楼门禁——检查工牌、验证身份,没权限的人进不来
JWT (JSON Web Token) 认证流程
1
用户
输入用户名密码,点击登录
2
网关/Nginx
转发登录请求到认证服务
3
认证服务
验证密码,生成 JWT Token(包含 Header、Payload、Signature)
4
用户/客户端
保存 Token(LocalStorage 或 Cookie)
5
后续请求
在 HTTP Header 中携带: Authorization: Bearer <Token>
6
网关/Nginx
校验 Token 签名和过期时间,通过后转发请求
7
后端服务
从 Token 中解析用户信息,处理业务逻辑
🔑 JWT Token 结构(Base64编码)
HEADER
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
{ "alg": "HS256", "typ": "JWT" }
.
PAYLOAD
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
{ "sub": "1234567890", "name": "John Doe", "iat": 1516239022 }
.
SIGNATURE
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
HMACSHA256(base64Url(header) + "." + base64Url(payload), secret)
🛠️ 三种方案实现对比
对比维度Session + CookieJWTOAuth2.0
存储位置 服务端存储 Session,客户端存 Cookie客户端存储 Token,服务端无状态授权服务器存储,客户端存 Access Token
扩展性 ❌ 需要共享 Session,扩展复杂✅ 无状态,易于水平扩展✅ 分布式架构,支持大规模系统
安全性 ⚠️ Cookie 可能被窃取,需要 CSRF 防护⚠️ Token 泄露风险,需 HTTPS + 短期有效✅ 行业最佳实践,支持多种安全机制
实现复杂度 🟢 简单,开箱即用🟡 中等,需要 Token 管理🔴 复杂,需要授权服务器
适用场景 传统 Web 应用、后台管理系统SPA、移动端 API、微服务第三方登录、开放平台、SSO
🔒 网关层认证最佳实践
1
统一在网关层验证
不要在每个微服务里重复写认证逻辑,统一在网关层校验 JWT 或 Session
2
HTTPS 强制
网关层强制 HTTPS,防止 Token 在传输过程中被窃取(中间人攻击)
3
Token 过期策略
Access Token 短期有效(15分钟),配合 Refresh Token 实现无感知续期
4
黑名单机制
用户登出或 Token 泄露时,将 Token 加入黑名单(Redis 存储)

6.2 HTTPS与SSL终结

为什么需要HTTPS?

  1. 安全: 防止数据在传输过程中被窃取
  2. 合规: 现代浏览器对HTTP网站显示"不安全"警告
  3. SEO: 搜索引擎优先收录HTTPS网站

SSL终结方案:

  • 只在网关层配置HTTPS和证书
  • 网关负责TLS握手和加解密
  • 网关和后端服务之间使用HTTP明文传输(内部网络可信)
  • 后端服务专注于业务逻辑,无需处理TLS

💡 SSL终结的优势

  • 简化管理: 证书只在网关配置,后端无需配置
  • 降低开销: 后端服务不需要处理TLS握手
  • 统一更新: 证书更新只需在网关操作
🔒 SSL 终结:HTTPS 流量的"解密官"
想象成公司的前台接待——对外使用正式头衔(HTTPS),对内用内部称呼(HTTP),负责"翻译"身份
🔐 HTTPS 流量解密流程
👤
客户端 (浏览器)
发起 HTTPS 请求
🔒TLS 加密连接
证书: *.example.com
算法: TLS 1.3
加密: AES-256-GCM
🚪
Nginx (SSL 终结)
📜 校验证书
🔓 解密流量
📝 添加 X-Forwarded-*
🔓HTTP 明文
X-Forwarded-For: 203.0.113.42
X-Forwarded-Proto: https
X-Real-IP: 203.0.113.42
⚙️
后端服务集群
专注于业务逻辑,无需处理 TLS
📜 SSL 证书管理
1
生成私钥
使用 OpenSSL 生成 RSA 私钥,这是证书的基础
openssl genrsa -out private.key 2048
2
创建 CSR
生成证书签名请求,包含域名和组织信息
openssl req -new -key private.key -out csr.pem
3
域名验证
CA 机构验证域名所有权(DNS 记录或 HTTP 文件)
# 添加 DNS TXT 记录 或 上传验证文件到 /.well-known/
4
签发证书
验证通过后,CA 签发证书文件
# 下载 certificate.crt 和 chain.crt
5
部署配置
将证书配置到 Nginx 并测试
nginx -t && systemctl reload nginx
✨ SSL 终结的核心优势
🚀
性能提升
TLS 握手和加密解密是 CPU 密集型操作,集中在 Nginx 处理,后端服务专注业务逻辑,整体吞吐量提升 2-5 倍
🔧
简化运维
证书统一管理,只需在 Nginx 配置一次,无需在每个后端服务重复配置,证书续期、更换一键完成
🛡️
集中安全
SSL/TLS 配置统一管控,强制使用最新协议版本和密码套件,统一添加安全响应头(HSTS、CSP 等)
📊
统一监控
所有 HTTPS 流量经过 Nginx,可以统一记录访问日志、分析 SSL 握手性能、监控证书有效期,便于审计和排障

7. 限流与熔断:如何防止系统被"流量洪水"冲垮?

7.1 限流算法对比

算法核心思想突发流量适用场景实现复杂度
令牌桶桶里装令牌,有令牌才能通过允许一定程度的突发API限流、带宽控制中等
漏桶请求进桶,匀速流出处理强制平滑,突发会被缓存或拒绝需要严格匀速处理的场景中等
滑动窗口统计时间窗口内的请求数严格按窗口计数,超出一律拒绝精确统计(如"1分钟内最多100次")较高

7.2 Nginx限流配置实战

nginx
# 定义限流区域(放在http块中)

# 1. 基于IP的限流(漏桶算法)
# zone=mylimit:10m - 区域名称和内存大小(10MB约可存储16万IP)
# rate=10r/s - 每秒允许10个请求
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;

# 2. 基于IP的连接数限制(防止单个IP建立过多连接)
limit_conn_zone $binary_remote_addr zone=addr:10m;

# 3. 基于服务端点的限流(不区分IP,保护后端整体)
limit_req_zone $server_name zone=server_limit:10m rate=100r/s;

server {
    listen 80;
    server_name api.example.com;

    # 用户服务 - 普通限流
    location /api/users/ {
        # 应用限流
        # burst=20 - 桶容量,允许突发20个请求
        # nodelay - 不延迟处理突发请求(立即处理或拒绝)
        limit_req zone=mylimit burst=20 nodelay;

        # 限制单个IP的连接数
        limit_conn addr 10;

        proxy_pass http://user-service;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    # 订单服务 - 更严格的限流
    location /api/orders/ {
        # 更严格的限流:每秒5个请求
        limit_req_zone $binary_remote_addr zone=order_limit:10m rate=5r/s;
        limit_req zone=order_limit burst=10 nodelay;

        proxy_pass http://order-service;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    # 限流后的处理
    # 当请求被限流时,返回429 Too Many Requests
    error_page 429 /429.html;
    location = /429.html {
        internal;
        return 429 '{"error": "Too Many Requests", "message": "Rate limit exceeded. Please try again later."}';
        add_header Content-Type application/json;
    }
}

💡 限流策略建议

  • 普通接口: 每秒10个请求,允许突发20个
  • 重要接口(支付、订单): 每秒5个请求,允许突发10个
  • 全局保护: 所有请求总和不超过每秒100个
⚡ 限流算法:系统不会被"流量洪水"冲垮的秘诀
想象成水坝的闸门——控制水流速度,防止下游被淹没
选择限流算法
🪙 令牌桶算法可视化
令牌桶
🪙
🪙
🪙
🪙
🪙
5 / 10 令牌
⏰ 令牌产生器 (2/秒)
🪙
🪙
🪙
📥 请求队列
📊 三种算法对比
维度令牌桶 (Token Bucket)漏桶 (Leaky Bucket)滑动窗口 (Sliding Window)
核心思想 桶里装令牌,有令牌才能通过请求进桶,匀速流出处理统计时间窗口内的请求数
突发流量 ✅ 允许一定程度的突发(桶里有令牌)❌ 强制平滑,突发会被缓存或拒绝❌ 严格按窗口计数,超出一律拒绝
适用场景 API 限流、带宽控制(允许突发)需要严格匀速处理的场景(如消息队列)精确统计(如"1分钟内最多100次")
实现复杂度 中等中等较高(需要记录每个时间窗口的请求)
Nginx 配置 limit_req_zone (漏桶)limit_req_zone (漏桶)需第三方模块或 Lua
📝 Nginx 限流配置示例
# 定义限流区域
# $binary_remote_addr: 按 IP 限流
# zone=mylimit:10m: 区域名称和大小
# rate=10r/s: 每秒最多10个请求
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;

server {
    listen 80;
    server_name api.example.com;

    location / {
        # 应用限流
        # burst=20: 桶容量,允许突发20个请求
        # nodelay: 不延迟处理突发请求
        limit_req zone=mylimit burst=20 nodelay;

        proxy_pass http://backend;
    }
}
💡 配置说明
  • limit_req_zone: 在 http 块中定义限流区域
  • $binary_remote_addr: 使用二进制 IP 地址作为限流键(省内存)
  • zone=mylimit:10m: 区域名称 mylimit,分配 10MB 内存
  • rate=10r/s: 每秒允许 10 个请求(漏桶算法)
  • burst=20: 桶的容量为 20,允许一定程度的突发流量
  • nodelay: 不延迟处理突发请求(立即处理或拒绝)

7.3 熔断:防止故障扩散

熔断器的工作原理:

  1. 关闭状态: 正常转发请求,同时统计错误率
  2. 开启状态: 当错误率超过阈值,熔断器开启,直接返回错误,不再转发请求
  3. 半开状态: 经过一段时间后,允许少量请求通过试探,如果成功则关闭熔断器

💡 核心思想

熔断就像电路保险丝: 电流过大时,保险丝自动熔断,保护整个电路不被烧毁。

类似地,当后端服务出现大量错误时,熔断器"跳闸",快速失败,防止故障扩散到整个系统。


8. 总结:网关设计的核心思维

8.1 核心原则回顾

原则含义实践要点
路由把请求送到正确的地方路径路由、域名路由、Header路由
负载均衡分摊流量到多台服务器轮询、加权、最少连接、IP哈希
安全守护系统大门认证鉴权、HTTPS、WAF
限流防止被流量冲垮令牌桶、漏桶、滑动窗口
熔断防止故障扩散快速失败、降级方案
可观测监控和排障日志、指标、链路追踪

8.2 技术选型建议

💡 选型决策树

选择网关:

├─ 只需要反向代理、负载均衡?
│  ├─ 是 → Nginx(首选)
│  └─ 否 → 继续

├─ 需要丰富的插件生态?
│  ├─ 是 → Kong(基于Nginx)
│  └─ 否 → 继续

├─ Spring Cloud 全家桶?
│  ├─ 是 → Spring Cloud Gateway
│  └─ 否 → Nginx

9. 名词速查表

名词英文解释
反向代理Reverse Proxy部署在服务器端,接收客户端请求并转发给内部服务的代理服务。客户端只知道反向代理的存在,不知道真实服务器地址。
正向代理Forward Proxy部署在客户端侧,代替客户端访问外部资源的代理服务。服务端看到的是代理的IP,不知道真实客户端。典型应用:VPN、翻墙工具。
API网关API Gateway位于客户端和后端服务之间的中间层,提供路由、认证、限流、日志等功能,是微服务架构的"统一大门"。
负载均衡Load Balancing将请求流量分配到多台服务器,避免单台服务器过载,提高系统可用性和性能。
SSL终结SSL Termination在网关层处理HTTPS加密解密,后端服务使用HTTP,降低后端计算开销,简化证书管理。
限流Rate Limiting限制单位时间内的请求数量,防止系统被突发流量压垮。常用算法:令牌桶、漏桶、滑动窗口。
熔断Circuit Breaking当依赖服务出现故障时,自动切断调用,防止故障扩散,并提供降级方案。
会话保持Session Persistence确保同一客户端的请求始终路由到同一台后端服务器,用于需要保持会话状态的场景。
健康检查Health Check定期检查后端服务的健康状态,自动剔除故障节点,保证流量只发送到健康的服务实例。
灰度发布Canary Release将少量流量导到新版本,验证稳定性后逐步扩大比例,降低发布风险。
WAFWeb Application FirewallWeb应用防火墙,防护SQL注入、XSS、CC攻击等Web安全威胁。
CDNContent Delivery Network内容分发网络,在全球部署边缘节点,加速静态资源访问。