Nginx同域名不同端口反向代理配置后出现404及连接失败问题求助
我先帮你梳理下核心问题:你想把本地localhost/api/buy/和localhost/api/sell/分别反向代理到example.com:80和example.com:82,但现在访问时既出现404错误,又有连接超时的提示(错误日志里的10060),换其他端口配置却能正常工作,想搞定同域名不同端口的代理问题对吧?
结合你的配置和错误日志,我给你分析下可能的原因和对应的解决办法:
一、先排查最核心的端口连通性问题
错误日志里的connect() failed (10060)是关键——这说明你的Nginx服务器根本连不上example.com:80和example.com:82这两个端口,这大概率是问题的根源。你提到换其他端口正常,那更说明这两个端口本身存在访问障碍:
- 可能是
example.com服务器的防火墙/安全组没开放80、82端口,把请求拦住了 - 目标服务根本没在这两个端口上运行(比如服务配置错了端口,或者进程没启动)
- 网络层面的限制:比如运营商屏蔽了这两个端口,或者Nginx所在服务器和目标服务器之间的路由不通
排查步骤:
在Nginx所在的服务器上手动测试连通性,用curl命令就行:
# 测试example.com:80的连通性 curl -v http://example.com:80 # 测试example.com:82的连通性 curl -v http://example.com:82
如果这两个命令也超时或者返回404,那先解决后端的连通性问题:
- 去
example.com服务器上检查防火墙/安全组规则,确保80、82端口对Nginx服务器的IP开放 - 用
netstat -tulpn或者ss -tulpn查看目标服务是否在80、82端口正常监听 - 如果是内网服务,确认Nginx服务器和目标服务器之间的网络是通的(比如ping、telnet测试)
二、调整HOST头配置解决后端路由问题
如果刚才的连通性测试是正常的,但还是返回404,那可能是你配置里的HOST头导致的问题。你当前设置了proxy_set_header HOST $host;,这里的$host是localhost(因为你的server_name是localhost)。如果example.com的后端服务依赖HOST头来匹配虚拟主机,那收到localhost这个HOST头后,它找不到对应的站点,就会返回404。
解决办法:把HOST头改成后端服务需要的example.com:
location /api/buy/ { proxy_set_header X-Real-IP $remote_addr; # 把HOST头替换成example.com,而不是localhost proxy_set_header HOST example.com; proxy_set_header X-NginX-Proxy true; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://example.com:80/; proxy_redirect off; } location /api/sell/ { proxy_set_header X-Real-IP $remote_addr; proxy_set_header HOST example.com; proxy_set_header X-NginX-Proxy true; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://example.com:82/; proxy_redirect off; }
三、额外的配置优化建议
- 添加超时配置,避免Nginx长时间等待无响应的后端:
在对应的location块或者server块里加上:proxy_connect_timeout 10s; # 连接超时时间 proxy_send_timeout 10s; # 发送请求超时时间 proxy_read_timeout 10s; # 读取响应超时时间 - 你的proxy_pass写法是对的:结尾带斜杠
http://example.com:80/会把/api/buy/后面的路径追加到后端地址后(比如localhost/api/buy/test会转发到http://example.com:80/test),如果不带斜杠反而会把完整路径加过去,不符合你的需求,所以不用改。
总结下:先优先搞定端口连通性问题,这是10060错误的直接原因;如果连通性没问题,再调整HOST头配置,应该就能解决404的问题了。
备注:内容来源于stack exchange,提问作者john_smith

