Nginx反向代理配置全解析:从入门到生产环境避坑,一篇讲透

为什么你的网站需要一个“前台接待员”?

做网站久了,你会发现一个有意思的现象:当业务稍微有点起色,服务器上跑的就不止一个服务了。可能前端是个 Node.js 应用,后端是 Java 的接口,数据库单独部署,再加上一个静态文件目录。这时候,让用户直接去访问这些乱七八糟的端口和地址,既不安全也不优雅。

Nginx 反向代理,就是那个站在所有服务前面的“前台接待员”。用户只需要记住一个域名、一个标准端口(80 或 443),剩下的路由分发、负载均衡、SSL 加密、静态资源缓存,全都由它一手包办。今天这篇,咱们不聊虚的,直接上手把配置捋一遍,顺便把那些容易踩的坑也一并填平。

反向代理到底“反”在哪?

很多新手容易把反向代理和正向代理搞混。简单打个比方:正向代理是你主动去找一个代理服务器,让它替你去访问外网资源(比如翻墙工具);反向代理则是客户端根本不知道后端服务器的存在,它只跟 Nginx 打交道,Nginx 再把请求转发给内网的真实服务。

这种模式带来的好处是实实在在的:

  • 安全隔离:后端服务器的真实 IP 和端口完全隐藏,外部只能看到 Nginx 的地址。
  • 负载均衡:一台 Nginx 可以把流量分发给多台后端应用服务器,横向扩展变得极其简单。
  • 统一入口:SSL 证书只需要在 Nginx 上配置一次,不用每台后端服务器都去折腾证书。

手把手:最基础的反向代理配置

假设你有一台服务器,上面跑着一个监听在 3000 端口的 Node.js 应用。现在你想让用户直接访问 http://yourdomain.com 就能看到这个应用,而不是去记那个带端口的地址。

Nginx 的配置文件通常位于 /etc/nginx/conf.d/ 目录下,我们新建一个 myapp.conf 文件:

server {
    listen 80;
    server_name yourdomain.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;
    }
}

保存后执行 nginx -t 检查语法,没问题就 systemctl reload nginx 重载配置。就这么简单,一个最基础的反向代理已经生效了。

这里有几个 header 参数需要特别留意:Host 必须带上,否则后端应用拿到的域名是 127.0.0.1,很多基于域名做路由的逻辑会直接失效;X-Real-IPX-Forwarded-For 用来传递客户端真实 IP,不然后端日志里看到的全是 Nginx 的内网地址,排查问题时会相当痛苦。

进阶:带路径的代理转发

有时候我们只想让某个特定路径走代理,其他路径由 Nginx 直接处理静态文件。比如 /api/ 开头的请求转发给后端,其他请求直接返回前端构建好的静态页面:

location /api/ {
    proxy_pass http://backend_server:8080/;
}

location / {
    root /var/www/frontend;
    index index.html;
}

注意 proxy_pass 后面那个 / 非常关键。带上斜杠,表示把 /api/ 前缀替换为空再转发;不带斜杠,则是把完整的原始 URI 原封不动传给后端。这个细节搞反了,后端接口路由大概率会 404。

WebSocket 与长连接:别让代理“掐断”你的实时通信

如果你的应用用到了 WebSocket(比如在线聊天、实时通知),上面的基础配置就不够用了。因为 WebSocket 协议需要先通过 HTTP 升级协议,Nginx 默认不会自动处理这个升级过程。

需要在 location 块里额外加上两行:

location /ws/ {
    proxy_pass http://ws_backend:9501;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_read_timeout 3600s;
}

proxy_read_timeout 建议设置得长一些,因为 WebSocket 连接是长时间保持的,默认的 60 秒超时会导致连接频繁断开。

负载均衡:让 Nginx 帮你“雨露均沾”

当单台后端服务器扛不住压力时,就得请出 Nginx 的 upstream 模块了。在 http 块里定义一个服务器组:

upstream backend_pool {
    server 192.168.1.10:8080 weight=3;
    server 192.168.1.11:8080 weight=1;
    server 192.168.1.12:8080 backup;
}

然后在 server 块里引用它:

location / {
    proxy_pass http://backend_pool;
}

这里的 weight 参数表示权重,数字越大被分配的请求越多。加了 backup 的服务器只在其他所有节点都挂掉时才会顶上,非常适合做灾备。Nginx 默认采用轮询算法,还有 ip_hash(按用户 IP 哈希,保证同一用户始终打到同一台服务器)等策略可选。

关于后端服务器的性能调优,建议配合阅读我们之前写过的 《别再盯着跑分看了!云服务器测评和性能调优,到底谁才是网站卡顿的“真凶”?》,很多时候瓶颈并不在 Nginx,而在后端应用本身。

SSL 证书配置:HTTPS 是标配,不是选配

现在部署 HTTPS 已经非常成熟了,用 Let’s Encrypt 的免费证书就能搞定。拿到证书文件后,在 Nginx 配置里加上监听 443 的 server 块:

server {
    listen 443 ssl http2;
    server_name yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;

    location / {
        proxy_pass http://backend_pool;
        # ... 其他 proxy_set_header 配置
    }
}

server {
    listen 80;
    server_name yourdomain.com;
    return 301 https://$host$request_uri;
}

第二个 server 块的作用是把所有 HTTP 请求 301 跳转到 HTTPS,防止用户访问旧链接时出现不安全提示。

生产环境避坑清单

配置写好了,网站跑起来了,但离“稳如老狗”还有一段距离。以下几个坑,是笔者在实际运维中踩过的,写出来给大家提个醒:

1. 代理缓冲与性能取舍

默认情况下,Nginx 会开启 proxy_buffering,也就是把后端响应先缓存到 Nginx 再发给客户端。这对大文件下载和慢客户端非常友好,能有效减轻后端压力。但对 SSE(Server-Sent Events)这类需要实时推送的场景,必须关闭缓冲:

proxy_buffering off;

2. 连接超时设置

后端接口偶尔响应慢是正常的,但如果 Nginx 的 proxy_connect_timeout 设置得太短,可能后端还在处理,Nginx 就已经报 504 了。建议设置:

proxy_connect_timeout 10s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;

3. 与 Docker 部署的联动

如果你的后端服务是跑在 Docker 容器里的,那 Nginx 的 proxy_pass 目标地址就不能写 localhost127.0.0.1 了,而应该写容器所在的宿主机 IP 或者 Docker 内部网络别名。这块细节比较多,建议参考我们整理的 《项目 Docker 容器化部署,从零到上线的完整操作手册》,里面讲得很透彻。

4. 304 状态码频发

很多朋友发现配置完反向代理后,浏览器里频繁出现 304 响应,担心是不是配置出了问题。其实这是 Nginx 在利用 HTTP 缓存协商机制,属于正常现象。想深入了解原理和排查方法,可以看看这篇 《Nginx 反向代理频繁出现 304 状态码?别慌,这篇文章帮你彻底搞懂它》

写在最后

Nginx 反向代理的配置本身并不复杂,难的是理解每个指令背后的网络语义,以及在不同业务场景下的取舍。配置完成后,别忘了顺手做一下基础的安全加固,比如限制内网访问、隐藏 Nginx 版本号等,具体操作可以参考这份 《Linux 服务器安全防护到底要做哪些?这份实战清单帮你堵住 90% 的漏洞》

另外,反向代理只是整个链路中的一环。如果你用的是云服务器,建议把 Nginx 的访问日志接入云监控,配合性能分析工具做持续观测——毕竟,代理层再快,后端应用拖后腿也是白搭。选一台配置靠谱的云主机,配上稳定的域名解析,再把这套代理配置吃透,你的网站离“高可用”就不远了。

希望这篇能帮你少走些弯路。有问题欢迎在评论区留言交流,咱们下篇见。

延伸阅读

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部