Nginx 反向代理最佳实践
下面是一份 最实用、最能落地的《Nginx 反向代理最佳实践》,结构清晰、生产级可直接复用。
location /api/ {
proxy_pass http://backend_api;
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_http_version 1.1;
proxy_set_header Connection "";
}
要点
- proxy_http_version 1.1 + Connection "" 避免后端 keepalive 异常
- 真实 IP 透传
- 不改 Host,后端可根据域名做路由或鉴权
❌ 错误示例(会多一层路径)
location /api/ {
proxy_pass http://backend/api/;
}
✅ 正确(严格遵守结尾 / 规则)
- location 有 /,proxy_pass 也必须带 /:
location /api/ {
proxy_pass http://backend_api/;
}
| location 结尾 | proxy_pass 结尾 | 结果 |
|---|---|---|
| /api/ | / | 去掉 /api/ 路径(推荐) |
| /api | 无 / | 不去掉 /api |
👉 最佳实践:location 和 proxy_pass 都带 /,最安全。
proxy_connect_timeout 3s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
send_timeout 30s;
理由
- 不加超时会造成大量 CLOSE_WAIT、TIME_WAIT、连接堆积
- 避免后端异常时 Nginx 阻塞
适用于 API + 静态资源代理:
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=api_cache:100m inactive=1d max_size=1g;
location /api/ {
proxy_cache api_cache;
proxy_cache_valid 200 1m;
proxy_cache_valid 404 10s;
}
upstream backend_api {
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;
}
```nginx
推荐策略
- **least_conn**:适用于长连接后端服务
- **ip_hash**:适用于 session 绑定
- **keepalive**:减少后端 TCP 建连成本
```nginx
upstream backend_api {
least_conn;
keepalive 100;
server 10.0.0.1:8000;
}
location /ws/ {
proxy_pass http://ws_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
client_max_body_size 200m;
proxy_request_buffering off; # 不在磁盘缓冲,减少 I/O
gzip_vary on;
gzip_proxied any;
gzip_types text/plain text/css application/json application/javascript;
避免代理后导致错乱的 gzip 类型。
很多人写:
proxy_set_header Host $host;
但生产推荐:
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $host;
这样后端更容易调试和获取入口上游的信息。
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Ssl on;
否则后端判断不清是 HTTP 还是 HTTPS。
real_ip_header X-Forwarded-For;
set_real_ip_from 0.0.0.0/0;
将代理链的最左端 IP 当作真实客户端 IP。
server {
listen 80;
server_name api.example.com;
client_max_body_size 100m;
location /api/ {
proxy_pass http://backend_api/;
# 保留客户端信息
proxy_set_header Host $http_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_http_version 1.1;
proxy_set_header Connection "";
proxy_buffering on;
# 超时
proxy_connect_timeout 3s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
# 缓存
proxy_cache api_cache;
proxy_cache_valid 200 1m;
proxy_cache_valid 404 10s;
}
}