Nginx 反向代理(Reverse Proxy)是让 Nginx 作为前端接受外部请求,再转发给后端应用的经典架构。无论是 Node.js、Python(Gunicorn/Uvicorn)、Java(Tomcat)还是其他语言写的服务,只要监听在本机某个端口,都可以让 Nginx 做前端代理,统一管理 SSL、日志、限流与请求头。本文讲清搬瓦工 VPS 上 Nginx 反向代理的核心配置。
本文要点
proxy_pass指令的写法与路径注意事项- 转发必要的请求头(真实 IP、Host 等)
- WebSocket 的额外配置
- upstream 块实现多后端与健康检查
- 常见代理错误的排查
反向代理的工作原理
客户端向 Nginx 发送请求 → Nginx 根据配置把请求转给后端(如 localhost:3000) → 后端处理后把响应返回给 Nginx → Nginx 再返回给客户端。整个过程中客户端只看到 Nginx 的 IP,后端应用不需要暴露在公网。
| 组件 | 角色 | 典型端口 |
|---|---|---|
| Nginx | 前端代理,处理 SSL、日志、限流 | 80 / 443 |
| Node.js / Python / Java | 后端应用,处理业务逻辑 | 3000 / 8000 / 8080 |
| 数据库 | 数据层,仅监听本地 | 3306 / 5432 |
最简单的反向代理配置
假设后端应用跑在本机 127.0.0.1:3000:
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://127.0.0.1:3000;
}
}转发必要的请求头
默认情况下,后端收到的 REMOTE_ADDR 是 127.0.0.1(Nginx 本身),丢失了真实客户端 IP。添加以下头部让后端能获取真实信息:
location / {
proxy_pass http://127.0.0.1:3000;
# 传递真实客户端 IP
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;
# 保留原始 Host
proxy_set_header Host $host;
# 关闭重定向自动修改
proxy_redirect off;
}后端应用如何获取真实 IP
X-Real-IP 或 X-Forwarded-For 头部,而非直接读 REMOTE_ADDR。各框架做法不同,请查阅对应文档。配置 WebSocket 支持
若后端应用使用 WebSocket,需要额外添加协议升级头:
location /ws/ {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 3600s; # 长连接超时
}用 upstream 定义上游
当后端有多个实例,或想给上游起一个易读的名字时,使用 upstream 块:
upstream backend_app {
server 127.0.0.1:3000;
server 127.0.0.1:3001; # 多个后端实例,轮询负载
keepalive 32; # 保持连接池
}
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://backend_app;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}超时参数调整
| 参数 | 默认值 | 说明 |
|---|---|---|
| proxy_connect_timeout | 60s | 连接上游超时 |
| proxy_send_timeout | 60s | 向上游发送超时 |
| proxy_read_timeout | 60s | 等待上游响应超时 |
对于响应慢的后端(如长时间运行的 API),适当加大 proxy_read_timeout,避免 504 Gateway Timeout。
不要把数据库直接暴露给代理
常见错误排查
- 502 Bad Gateway:后端服务未启动或监听地址/端口不对,检查
proxy_pass地址 - 504 Gateway Timeout:后端响应太慢,加大
proxy_read_timeout - 400 Bad Request:后端对 Host 头有要求,确认
proxy_set_header Host写正确
小结
proxy_pass指向后端地址,注意末尾斜杠影响路径拼接- 必须转发 X-Real-IP、X-Forwarded-For、Host 等头部
- WebSocket 需额外加 Upgrade / Connection 头
- upstream 块适合多后端或统一命名
常见问题
proxy_pass 末尾加不加斜杠有什么区别?
有区别。proxy_pass http://127.0.0.1:3000/(有斜杠)会把 location 匹配的前缀去掉再拼接;无斜杠则把完整 URI 转发。通常代理根路径时两者等效,代理子路径时需注意。
后端是 HTTPS 需要特别配置吗?
需要把 proxy_pass 改为 https:// 并根据情况配置 proxy_ssl_verify on/off。若后端用自签名证书,可设置 proxy_ssl_verify off(仅内网可信环境)。
如何限制只允许 Nginx 访问后端端口?
让后端绑定 127.0.0.1(而非 0.0.0.0),这样只有本机进程能连接。配合防火墙不对外开放后端端口,双重保护。