反向代理是 Nginx 最核心的用法之一:它挡在真实应用前面,把外部请求转发给后端服务,对外只暴露一个入口。本文从最基础的转发讲起,逐步覆盖 HTTPS、负载均衡、WebSocket 代理与高频故障排查。
一、什么是反向代理
正向代理替客户端发请求(如翻墙代理),反向代理替服务端接收请求:用户访问 Nginx,Nginx 再把请求交给后端的 Node、Java、Python 等应用处理,结果原路返回。对用户来说,它只跟 Nginx 打交道。
- 隐藏后端:真实服务跑在内网端口,不直接暴露
- 统一入口:一个 80/443 端口对外,内部多个服务复用
- SSL 卸载:证书只在 Nginx 上配置,后端走明文更高效
- 负载均衡:把流量分摊到多台后端,提升可用性
二、安装与配置文件结构
Debian/Ubuntu 安装:
apt-get update && apt-get install -y nginx
systemctl enable nginx && systemctl start nginx
配置文件通常分散在 /etc/nginx/ 目录下:
/etc/nginx/nginx.conf # 主配置
/etc/nginx/conf.d/*.conf # 独立站点配置(推荐放这里)
/etc/nginx/sites-enabled/ # 另一处站点配置(Debian 系)
建议每个站点一个独立 .conf 文件放到 conf.d/,修改后执行 nginx -t 校验语法,再 systemctl reload nginx 热加载。
三、基础反向代理:转发到后端应用
假设后端 Node 服务监听 127.0.0.1:3000,用下面这段配置把它暴露到 80 端口:
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:3000;
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_set_header 很关键:把真实的主机名、客户端 IP、协议透传给后端,否则后端拿到的全是 Nginx 自己的信息,导致日志、跳转、鉴权出错。
四、proxy_pass 的路径拼接规则
这是最容易踩坑的地方,proxy_pass 后面带不带 / 行为完全不同:
# 情况 A:不带斜杠 —— 保留 location 路径
location /api/ {
proxy_pass http://127.0.0.1:3000;
}
# 访问 /api/user → 转发到 http://127.0.0.1:3000/api/user
# 情况 B:带斜杠 —— 用 / 替换掉 location 匹配部分
location /api/ {
proxy_pass http://127.0.0.1:3000/;
}
# 访问 /api/user → 转发到 http://127.0.0.1:3000/user
# 情况 C:带路径前缀
location /api/ {
proxy_pass http://127.0.0.1:3000/service/;
}
# 访问 /api/user → 转发到 http://127.0.0.1:3000/service/user
记住一条口诀:proxy_pass 末尾有斜杠,location 匹配到的路径被替换掉;没有斜杠,原样拼接。
五、HTTPS:证书配置与强制跳转
用 Let's Encrypt 免费证书为例(假设证书已签发到 /etc/ssl/):
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/ssl/example.com/fullchain.pem;
ssl_certificate_key /etc/ssl/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_session_cache shared:SSL:10m;
location / {
proxy_pass http://127.0.0.1:3000;
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;
}
}
# 80 端口全部跳转到 HTTPS
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
证书到期前用 certbot renew 续期,Nginx 配置无需改动。
六、负载均衡:upstream 模块
当后端有多台实例时,用 upstream 定义一组服务器,Nginx 自动分发流量:
upstream backend {
# 默认轮询;可加权重
server 127.0.0.1:3001 weight=3;
server 127.0.0.1:3002 weight=1;
server 10.0.0.5:3000;
# 同一个客户端 IP 固定落到同一台,解决登录态问题
# ip_hash;
# 谁连接数最少分给谁(需 Nginx Plus 或较新开源版)
# least_conn;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend;
}
}
常用调度方式:
- 轮询(默认):按顺序轮流分配,适合后端性能一致的场景
- weight 权重:性能高的机器给更大的 weight
- ip_hash:按客户端 IP 哈希,保证同一用户落到同一台,适合有状态服务
- least_conn:优先分给活跃连接最少的后端,更均衡
配合被动健康检查剔除故障节点:
upstream backend {
server 127.0.0.1:3001 max_fails=3 fail_timeout=30s;
server 127.0.0.1:3002 max_fails=3 fail_timeout=30s;
}
某后端连续 3 次探测失败(30 秒内),Nginx 会暂时把它摘掉,恢复后再加回。
七、WebSocket 与长连接代理
WebSocket 需要额外透传 Upgrade 头,否则连接建立后会立刻断掉:
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; # 长连接别被默认 60s 超时切断
}
八、常见故障排查
1. 502 Bad Gateway
含义是「Nginx 连不上后端」。按以下顺序查:
- 后端进程是否真的在跑:
curl http://127.0.0.1:3000本地直连验证 proxy_pass的地址/端口是否写错- 防火墙或 SELinux 是否拦了本地回环外的连接
- 后端监听的是
127.0.0.1还是0.0.0.0,只监听前者时外网 IP 访问会失败
2. 504 Gateway Timeout
后端太慢,Nginx 等不及。调大超时:
proxy_connect_timeout 10s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
3. 后端拿到的 IP 都是 Nginx 的
漏了 proxy_set_header X-Real-IP $remote_addr; 和 X-Forwarded-For,应用里要改用这两个头取真实 IP。
4. 静态资源 404 / 样式错乱
多半是 proxy_pass 斜杠规则导致路径被改写,对照「第四章」检查 location 与 proxy_pass 的匹配关系。
九、性能与安全加固
- 开启 upstream 连接复用:在 upstream 里加
keepalive 32;,并配对proxy_http_version 1.1; proxy_set_header Connection "";,减少 TCP 握手开销 - 限制请求体大小:
client_max_body_size 20m;防止大文件打爆后端 - 隐藏版本号:
server_tokens off;避免泄露 Nginx 版本便于针对性攻击 - 开启缓冲:默认
proxy_buffering on;可让慢客户端不拖累后端,必要时再关 - 加基础限流:用
limit_req_zone防简单 CC 攻击
Nginx 反向代理是搭建现代 Web 服务的基础件:配好转发头、理清 proxy_pass 路径规则、再用 upstream 做负载均衡,就能用一台 Nginx 稳稳兜住多套后端服务。配合本文的排查清单,绝大多数 502/504 问题都能快速定位。

发表评论 取消回复