Nginx反向代理总是配不好?从零到一拆解配置逻辑,顺便聊聊那些坑

说实话,Nginx 这东西,你用好了,它就是个听话的门卫;配不好,它就是个让你抓狂的“拦路虎”。尤其是反向代理,很多朋友一开始接触,总被那些 location、proxy_pass 的规则绕得晕头转向。

今天咱们不聊那些虚头巴脑的理论,直接上手,把 Nginx 反向代理的底层逻辑和实操配置掰开揉碎了讲清楚。看完这篇,你至少能解决 90% 的常见问题。

一、反向代理到底是个啥?先搞懂逻辑再动手

💡 推荐阅读:挑云服务器只看CPU和内存?这几个配置参数才是真正的“隐藏坑”

咱们用大白话解释。你开了一家奶茶店(你的业务服务器),但你不能让顾客直接冲进后厨点单吧?所以你在前台设了一个收银台(Nginx)。

顾客(用户请求)只跟收银台说话,收银台再把单子转给后厨(内网服务)。顾客根本不知道后厨长啥样,也接触不到后厨。这就是反向代理的核心:屏蔽内网细节,统一入口调度。

明白了这个逻辑,你再看 Nginx 配置,就清晰多了。它主要做三件事:

  • 接收请求:监听 80 或 443 端口。
  • 转发请求:根据规则,把请求扔给后面的真实服务器。
  • 带回响应:把真实服务器的结果,原封不动地还给用户。

二、最基础的配置:一个 server 块搞定

咱们直接看一个最典型的配置片段。假设你有一台服务器 IP 是 192.168.1.10,上面跑着一个 Java 应用,端口是 8080。现在你想让用户直接访问服务器的 80 端口就能用。

server {
    listen       80;
    server_name  yourdomain.com;

    location / {
        proxy_pass http://192.168.1.10:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

这里有几个关键点,笔者得给你划重点:

1. proxy_pass 末尾的斜杠,千万别乱加

这是新手最容易踩的坑。看下面两个例子:

  • 带斜杠:proxy_pass http://192.168.1.10:8080/; —— 这表示把 location 匹配的路径替换掉
  • 不带斜杠:proxy_pass http://192.168.1.10:8080; —— 这表示把请求原样拼接到后面。

举个例子,用户访问 /api/login

配置方式 后端实际接收 效果
带斜杠 8080/ /login 路径被替换,常用于前后端分离项目
不带斜杠 8080 /api/login 路径原样保留,常用于整体转发

记住一句话:如果你的 location 是 /api/,且 proxy_pass 末尾加了 /,那么 /api/ 就会被吃掉。这是很多接口 404 的元凶。

2. 请求头设置,关乎应用安全与日志

上面配置里那三行 proxy_set_header 建议都写上。它们的作用是:

  • Host $host:让后端知道用户访问的是哪个域名,防止多个站点共用一个后端时串台。
  • X-Real-IPX-Forwarded-For:把用户的真实 IP 传给后端。不然后端看到的全是 Nginx 的 IP,做不了访问控制和风控。

三、进阶玩法:按路径分流与负载均衡

很多时候,一台服务器上不止一个服务。比如图片服务、接口服务、前端页面。这时候就需要用 location 做精细化的路由。

场景:动静分离

# 静态资源直接由 Nginx 处理,不走后端
location ~* \.(jpg|jpeg|png|gif|css|js)$ {
    root /data/static;
    expires 30d;
    access_log off;
}

# 动态请求转发给 Tomcat
location / {
    proxy_pass http://192.168.1.10:8080;
    proxy_set_header Host $host;
}

这样配置的好处是显而易见的:图片、CSS、JS 这些静态文件由 Nginx 直接返回,速度极快,不占用后端资源。后端只处理 API 请求,压力骤减。

场景:负载均衡(Upstream)

如果你的业务量上来了,一台后端扛不住了,Nginx 可以帮你把请求分发到多台服务器上。

upstream backend_servers {
    server 192.168.1.10:8080 weight=3;
    server 192.168.1.11:8080 weight=1;
    server 192.168.1.12:8080 down;  # 手动下线一台
}

server {
    listen 80;
    server_name yourdomain.com;

    location / {
        proxy_pass http://backend_servers;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

这里的 weight 代表权重,数字越大,分到的请求越多。默认是轮询。用 down 可以临时摘除某台服务器,不用改代码,非常方便。

四、WebSocket 与 HTTPS 的特殊处理

如果你代理的是 WebSocket 服务(比如在线聊天、实时推送),必须加两行配置,否则会一直连接失败:

location /ws/ {
    proxy_pass http://192.168.1.10:8080;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

原理不深究,记住这是 WebSocket 协议升级的握手信号即可。

至于 HTTPS,其实就是在 server 块里多监听一个 443 端口,并指定证书路径。这里要提醒一句:证书一定要买正规的,或者用 Let‘s Encrypt 免费签发的。 千万别用那些不受信任的自签名证书,否则用户浏览器会直接拦截,体验极差。

五、几个容易忽略的“隐形坑”

最后,笔者结合自己的实操经验,给大家排几个雷。这些坑不踩不知道,一踩一个准。

  • 缓冲区设置:如果你代理的是大文件下载,建议关掉缓冲或者调大缓冲,不然 Nginx 会先把整个响应缓存到磁盘再发给用户,速度反而慢。可以加 proxy_buffering off; 试试。
  • 超时时间:默认的 proxy_read_timeout 是 60 秒。如果你的后端接口处理时间较长,比如导出报表,一定要调大这个值,否则用户会看到 504 Gateway Timeout。建议设置为 proxy_read_timeout 300s;
  • 防火墙与 SELinux:如果你在 CentOS 上配置好了,但一直报 502,先别怀疑 Nginx 配置。检查一下防火墙是否放行了 8080 端口,以及 SELinux 是否拦截了 Nginx 对外访问。很多时候问题不在 Nginx,而在系统层面。
  • 配置语法检查:改完配置,一定要执行 nginx -t 检查语法,然后再 nginx -s reload 平滑重载。千万别直接 restart,那样会瞬间断开所有连接,造成业务闪断。

其实 Nginx 反向代理的配置并不复杂,核心就是理解 proxy_pass 的路径替换逻辑,以及请求头的传递。把这几个点吃透了,你就能应对绝大多数场景。如果你刚接触服务器,笔者建议你选一台稳定靠谱的云厂商,毕竟配置再对,机器三天两头宕机也是白搭。正规的云服务商对网络质量、安全防护都有保障,能让你少操很多心。

希望这篇文章能帮你把 Nginx 这块硬骨头啃下来。如果你在配置中遇到了什么奇怪的问题,欢迎在评论区留言,咱们一起探讨。

延伸阅读

滚动至顶部