Nginx同类型反向代理配置单个实例正常、多实例共存时第二个返回404求助
嗨,我太懂这种单个配置正常、放一起就掉链子的糟心感了!咱们来一步步拆解你的问题,先把你贴的配置放出来方便分析:
upstream blog { server 127.0.0.1:3001; } upstream api { server 127.0.0.1:3000; } server { listen 80; listen [::]:80; server_name local.net www.local.net; location /blog/ { rewrite ^/blog(.*)$ $1 break; proxy_pass http://blog/; include proxy_params; } } server { listen 80; listen [::]:80; server_name api.local.net; location /api/ { rewrite ^/api(.*)$ $1 break; proxy_pass http://api/; include proxy_params; } }
结合你的描述,我猜大概率是这几个原因导致的,咱们挨个排查:
1. 域名解析没到位
你有没有在本地hosts文件里加api.local.net的解析?如果只配置了local.net和www.local.net指向127.0.0.1,但漏掉了api.local.net,那你访问api.local.net时,请求根本不会落到第二个server块,反而会被第一个server(或者Nginx的默认server)接手,而第一个server里没有匹配/api/的规则,自然返回404。
解决办法:
- Linux/macOS:编辑
/etc/hosts,添加一行:127.0.0.1 api.local.net - Windows:编辑
C:\Windows\System32\drivers\etc\hosts,同样添加上述内容
2. 请求路径不匹配
你的第二个server块只配置了location /api/,也就是说只有访问api.local.net/api/xxx这种带/api/前缀的路径才会触发反向代理。如果直接访问api.local.net(不带/api/前缀),Nginx找不到对应的location规则,就会返回默认的404页面。
如果想让api.local.net的根路径也能代理到后端,可以加一个根路径的location:
server { listen 80; listen [::]:80; server_name api.local.net; # 处理根路径请求 location / { proxy_pass http://api/; include proxy_params; } location /api/ { rewrite ^/api(.*)$ $1 break; proxy_pass http://api/; include proxy_params; } }
3. Nginx配置没重载
你修改完配置后,有没有执行重载命令让新配置生效?如果只是保存了文件但没重载,Nginx还是用的旧配置,自然不会加载第二个server块。
先检查配置语法是否正确:
sudo nginx -t
没问题的话再重载配置:
sudo nginx -s reload
4. 默认server的干扰
如果你的Nginx里还有其他带default_server标记的配置,或者第一个server因为加载顺序默认成为了全局默认server,当api.local.net解析出问题时,请求会落到默认server,导致404。这种情况先优先解决域名解析的问题,要是还不行,可以给第二个server的listen加上default_server试试。
先从上面这几点排查,应该能解决你的问题!
备注:内容来源于stack exchange,提问作者georgy

