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 反向代理的最佳实践(避免依赖默认行为)。

相关推荐
东风微鸣2 小时前
Apache Parquet 优势与日志应用场景解析
运维·apache
Danileaf_Guo2 小时前
256台H100服务器算力中心业务集群部署方案
运维·服务器
掘根2 小时前
【消息队列项目】连接管理模块实现
运维·服务器
不想画图2 小时前
Docker 容器核心配置实战:资源管控、数据卷与容器互联
运维·docker·容器
wheeldown2 小时前
【Linux网络编程】网络基础之MAC地址与IP地址的区别
linux·运维·网络·macos
2501_941982052 小时前
外部群自动化中的“静默心跳”存活检测
运维·自动化
Mr-Wanter2 小时前
搭建局域网时间同步服务器
java·运维·服务器
有谁看见我的剑了?2 小时前
ESXI 虚拟机文件组成学习
运维·学习·云计算
代码游侠2 小时前
应用——UDP 网络编程
linux·运维·开发语言·学习·算法