Nginx upstream 负载均衡 404,单节点转发正常的根因与解决

一、问题现象

  1. 核心配置
    nginx

后端节点集群配置

upstream backend_servers {

server 192.168.1.10:8080;

server 192.168.1.11:8080;

server 192.168.1.12:8080;

}

server {

listen 80;

server_name 192.168.1.30;

复制代码
client_max_body_size 50M;     
 
location / {
    root   /usr/share/nginx/html/admin;
    index  index.html index.htm;
    try_files $uri $uri/ /index.html; 
}    
   
# 异常的接口转发配置
location /admin-api/ {     
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;   
    proxy_pass http://backend_servers;
}

}

  1. 问题表现

访问 http://192.168.1.30/admin-api/server/ 前缀的接口,持续返回 404;

若将 proxy_pass http://backend_servers; 替换为单节点 proxy_pass http://192.168.1.12:8080;,接口可正常访问;

单独测试集群内每台后端节点(192.168.1.10/11/12:8080)的 admin-api/server/ 接口,均返回正常,无 404 问题。

二、排查过程

  1. 初步排除常见问题
    排除后端节点故障:所有节点单独访问接口正常,无服务未启动 / 接口缺失问题;
    排除路径拼接问题:单节点转发未加尾斜杠仍正常,说明后端支持 /admin-api/server/ 完整路径;
    排除网络连通性:Nginx 服务器可正常 telnet 所有后端节点的 8080 端口,无防火墙拦截。
  2. 关键验证:模拟 upstream 转发请求
    通过 curl 模拟 Nginx upstream 的转发行为,发现核心差异:
    bash
    运行

模拟upstream转发(带Host: backend_servers),返回404

curl -v -H "Host: backend_servers" http://192.168.1.12:8080/admin-api/server/

模拟单节点转发(带Host: 192.168.1.12:8080),返回正常

curl -v -H "Host: 192.168.1.12:8080" http://192.168.1.12:8080/admin-api/server/

结论:upstream 模式下 Nginx 默认传递的 Host 头异常,导致后端服务识别失败。

三、根因分析

Nginx upstream 转发时,若未显式配置proxy_set_header Host,会默认将Host头设置为 upstream 集群名称(如backend_servers),而非客户端请求的 Host 或后端节点的 IP: 端口。

后端服务通常依赖Host头做路由匹配、域名鉴权或反向代理识别,当收到Host: backend_servers这种非预期值时,会判定为非法请求,返回 404;而单节点转发时,Nginx 隐式传递Host: 后端IP:端口,后端能正常识别,因此请求成功。

四、解决方案

  1. 核心修复:显式配置 Host 头
    在接口转发的 location 块中添加proxy_set_header Host host;,强制传递客户端请求的 Host 头(或后端识别的固定 Host): nginx location /admin-api/ { proxy_set_header X-Real-IP remote_addr;
    proxy_set_header X-Forwarded-For proxy_add_x_forwarded_for; proxy_set_header Host host; # 关键:传递客户端请求的Host(如192.168.1.30)

    若后端需固定Host,可替换为:proxy_set_header Host "192.168.1.12:8080";

    proxy_pass http://backend_servers;
    }

  2. 配置生效
    bash
    运行

检查配置语法

nginx -t

平滑重启Nginx

nginx -s reload

  1. 生产环境优化(可选)

为避免后续节点故障 / 异常导致 404,补充 upstream 健康检查和连接优化:

nginx

upstream backend_servers {

server 192.168.1.10:8080 max_fails=3 fail_timeout=10s;

server 192.168.1.11:8080 max_fails=3 fail_timeout=10s;

server 192.168.1.12:8080 max_fails=3 fail_timeout=10s;

keepalive 32; # 长连接优化

}

location /admin-api/ {

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header Host $host;

proxy_http_version 1.1; # 强制HTTP/1.1,避免连接兼容问题

proxy_pass http://backend_servers;

}

五、总结

Nginx upstream 负载均衡与单节点转发的核心差异之一是Host头的默认传递规则,当出现「单节点正常、集群 404」且后端节点无故障时,优先排查:

是否缺失Host头配置;

是否有其他关键请求头(如 X-Forwarded-Host)未传递;

upstream 集群名称是否被后端服务拦截。

显式配置proxy_set_header Host $host;是解决此类问题的关键,也是 Nginx 反向代理的最佳实践(避免依赖默认行为)。

相关推荐
Java.熵减码农5 小时前
解决Linux修改环境变量后导致登录循环进不去系统的问题
linux·运维·服务器
明天好,会的5 小时前
分形生成实验(五):人机协同破局--30万token揭示Actix-web状态管理的微妙边界
运维·服务器·前端
猫头虎5 小时前
如何在浏览器里体验 Windows在线模拟器:2026最新在线windows模拟器资源合集与技术揭秘
运维·网络·windows·系统架构·开源·运维开发·开源软件
C_心欲无痕6 小时前
nginx - alias 和 root 的区别详解
运维·前端·nginx
徐同保6 小时前
nginx转发,指向一个可以正常访问的网站
linux·服务器·nginx
HIT_Weston6 小时前
95、【Ubuntu】【Hugo】搭建私人博客:_default&partials
linux·运维·ubuntu
实心儿儿7 小时前
Linux —— 基础开发工具5
linux·运维·算法
oMcLin7 小时前
如何在SUSE Linux Enterprise Server 15 SP4上通过配置并优化ZFS存储池,提升文件存储与数据备份的效率?
java·linux·运维
SelectDB7 小时前
驾驭 CPU 与编译器:Apache Doris 实现极致性能的底层逻辑
运维·数据库·apache
❀͜͡傀儡师8 小时前
docker部署Arcane容器可视化管理平台
运维·docker·容器