反向代理是 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 问题都能快速定位。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部