同一服务器上Nginx Upstream子域名的负载均衡配置问题
先看你给出的Nginx配置,你已经用Upstream模块搭起了一个基于子域名的负载均衡框架(虽然目前只有一个可用节点),我来帮你拆解这里面的关键细节,以及这类子域名场景下的常见配置要点和优化建议:
1. Upstream块中子域名的作用与状态配置
你的upstream load块里定义了两个子域名节点:
server loadapi.example.com;:这是当前活跃的后端节点,Nginx会把所有转发请求导向这个子域名对应的服务器server loadapi.anotherdomain.com down;:down标记是用来标记节点暂时不可用的,Nginx不会把请求转发到这里,一般用于临时下线节点做维护或者故障排查
这里有个容易踩坑的点:Nginx默认会在启动或重载配置时解析这些子域名的IP,之后会缓存这个解析结果。如果你的后端子域名IP经常变动(比如用了动态DNS),就得配置DNS解析器并开启定期重解析,不然Nginx会一直用旧IP导致请求失败,示例配置如下:
upstream load { server loadapi.example.com; server loadapi.anotherdomain.com down; resolver 8.8.8.8 valid=30s; # 指定公共DNS服务器,每30秒重新解析一次子域名 }
2. 反向代理与Upstream的关联优化
你的server api.example.com块通过proxy_pass http://load;把根路径的所有请求转发到load这个Upstream池,这里有个很重要的配置建议:
你注释掉的proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;强烈建议开启!因为默认情况下,后端loadapi.example.com的服务拿到的客户端IP是Nginx服务器的IP,而不是真实的用户IP。开启后后端就能获取到真实请求来源,方便日志统计或权限控制。另外还可以根据需求配置Host头,完整示例:
location / { proxy_pass http://load; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; # 如果后端需要原请求的Host(也就是api.example.com)就用这个;如果需要后端节点的Host(loadapi.example.com)可以换成$proxy_host }
3. 子域名Server块的访问控制
你单独配置了server loadapi.example.com块,直接指向本地项目目录,这意味着这个子域名既可以作为Upstream的后端节点,也能被用户直接访问。如果不想让用户绕过代理直接访问后端节点,可以加个访问限制:
- 只允许Nginx自身访问:
server { listen 80; server_name loadapi.example.com; allow 127.0.0.1; # 允许本地回环地址访问 deny all; # 拒绝其他所有来源 root /disk/projects/load/loadapi; index index.html index.htm index.shtml index.php; ... ... error_page 404 /404.html; }
- 或者只接受来自反向代理的请求(通过X-Forwarded-For判断):
server { listen 80; server_name loadapi.example.com; # 如果请求没有X-Forwarded-For头,说明不是来自反向代理,直接返回403 if ($http_x_forwarded_for = "") { return 403; } root /disk/projects/load/loadapi; ... ... }
4. 负载均衡策略扩展(后续扩容用)
目前你的Upstream只有一个可用节点,等后续要加更多子域名节点时,可以根据业务需求配置不同的负载均衡策略:
- 默认轮询:Nginx会按顺序把请求转发到每个节点,适合节点性能相近的场景
- 加权轮询:给性能好的节点设置更高权重,让它接收更多请求:
upstream load { server loadapi.example.com weight=3; # 权重3,接收3/4的请求 server loadapi2.example.com weight=1; # 权重1,接收1/4的请求 }
- IP哈希:根据客户端IP的哈希值转发请求,确保同一用户始终访问同一个节点,适合需要会话保持的业务:
upstream load { ip_hash; # 开启IP哈希策略 server loadapi.example.com; server loadapi2.example.com; }
内容的提问来源于stack exchange,提问作者shady

