Nginx 反向代理详解
下面是 一份深入但非常易懂的《Nginx 反向代理详解》,包含概念、机制、核心指令、生产级配置、调优思路、最佳实践、常见坑点,一看就能直接应用到你的项目(FastAPI / Umi / React / PostgreSQL / Redis 等)。
- 正向代理(客户端 -> 代理 -> 服务器)
- 反向代理(客户端 -> Nginx -> 后端应用)
反向代理隐藏后端服务,统一入口,使系统具有:
- 统一出口(统一域名)
- 负载均衡
- 缓存能力
- 安全防护
- SSL offload(证书终止)
- 降低跨域复杂性
- 提升性能
下面是最核心的关键:
例如:
GET /api/user HTTP/1.1
Host: api.example.com
匹配 server_name、listen 和 location。
Nginx 转发整个请求(含 header、body)到后端,例如 FastAPI / Flask / Java / Node。
Nginx 再把响应返回给客户端。
最核心的指令。
proxy_pass http://127.0.0.1:8000;
trailing slash 大坑(必须掌握)
location /api/ {
proxy_pass http://backend/; # 去掉前缀 /api/
}
location /api/ {
proxy_pass http://backend; # 保留前缀 /api/
}
这是反向代理最容易踩的坑。
proxy_set_header Host $host;
proxy_set_header X-Real-IP $proxy_protocol_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
作用:
| Header | 用途 |
|---|---|
| Host | 保持原始域名(如 api.xxx.com) |
| X-Real-IP | 客户端真实 IP |
| X-Forwarded-For | 多级代理 IP 链条 |
| X-Forwarded-Proto | HTTP/HTTPS |
生产必须:
proxy_http_version 1.1;
proxy_set_header Connection "";
提升吞吐量 2~5 倍(保持长连接)。
proxy_connect_timeout 3s;
proxy_read_timeout 30s;
proxy_send_timeout 30s;
- connect 要短(3s)
- read/send 可长(根据业务)
避免节点卡死导致全站可用性下降。
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_next_upstream_tries 3;
大幅提升可用性。
Client -> Nginx -> Upstream backend -> Nginx -> Client
Nginx 会:
- 接收请求
- 解析请求
- 匹配 location
- 根据 proxy_pass 转发到后端
- 管理后端连接池
- 读取响应(缓冲)
- gzip 压缩
- 写回客户端
反向代理不仅是转发,更是请求生命周期的代理器。
upstream api_backend {
least_conn;
server 10.0.0.1:8000 max_fails=3 fail_timeout=30s;
server 10.0.0.2:8000 max_fails=3 fail_timeout=30s;
keepalive 50;
}
关键点:
- least_conn -> 防止慢节点被分配更多流量
- max_fails / fail_timeout -> 故障剔除
- keepalive 50 -> 连接复用提高性能
- 支持 session sticky(商业版)
- 支持四层负载(stream)
适配你当前技术栈(FastAPI + React + Umi)
server {
listen 443 ssl;
http2 on;
server_name api.example.com;
# SSL
ssl_certificate /etc/nginx/ssl/example.pem;
ssl_certificate_key /etc/nginx/ssl/example.key;
# proxy settings
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 3s;
proxy_read_timeout 30s;
proxy_send_timeout 30s;
access_log /data/nginx/logs/api.log;
location /api/ {
proxy_pass http://api_backend;
}
}
- 一定要开 keepalive(后端压力骤降)
- connect_timeout 必须短(3s)
- 关闭 Connection: close(提升吞吐)
- upstream 必须 least_conn(避免卡顿扩散)
- 合理配置 proxy_buffer_size(防止大 header)
- 关闭 client_max_body_size 限制或按需设置
- API 请求避免 gzip=on(前端文件才需要)
- 隐藏后端 IP
- 强制 HTTPS
- 限制 HTTP method(如后台接口)
- 限速(rate limiting)
- 做 request_size 限制
- 错误页面不暴露后端信息
❌ 1. 有 / 和没 / 的 proxy_pass
导致路径错乱
❌ 2. 忘了设置 Host header
后端服务会以为你是 default host
❌ 3. 没清空 Connection header
大量短连接 -> 性能崩溃
❌ 4. upstream 不设失败重试
一个节点挂掉 -> 全站 504
❌ 5. client_body_buffer_size 过小
POST 大 body 错误 413