问题背景
最近我在部署一个项目时遇到了一个棘手的问题:在一台服务器上同时部署了博客网站(使用域名aimaji.top
访问)和后台管理系统(直接使用服务器IP访问)。部署完成后,后台管理系统调用接口时一直报超时错误。
初步排查
首先我意识到问题可能出在跨域访问上:
-
博客使用域名访问
-
后台使用IP访问
-
两者需要调用相同的API接口
Nginx代理配置
我尝试通过Nginx配置代理来解决这个问题:
location /api { proxy_pass http://aimaji.top/api; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }
这个配置的目的是将所有以/api
开头的请求转发到http://aimaji.top/api
。然而,配置后接口一直无响应,报504网关超时错误。
深入排查:查看Nginx错误日志
通过查看Nginx错误日志(/www/wwwlogs/***.error.log
),发现了关键错误信息:
[error] 2943572#0: *13293 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 120.79.69.***, server: 120.79.69.***, request: "GET /api/administrator HTTP/1.1", upstream: "http://120.79.69.***/api/administrator", host: "120.79.69.***"
发现问题所在
从错误日志可以看出:
-
我配置的
proxy_pass http://aimaji.top/api
本应转发到aimaji.top
-
但实际上请求被转发到了服务器自身的IP地址
120.79.69.***
-
这导致了请求循环和超时
解决方案
问题出在Host
头的设置上。我原本使用$host
变量(即客户端请求的Host头),这导致Nginx将请求转发到自身。正确的做法是指定目标主机:
location /api { proxy_pass http://aimaji.top/api; proxy_set_header Host aimaji.top; # 明确指定目标主机 # 其他配置... }
为什么这样能解决问题?
-
Host头的重要性:很多Web服务器使用Host头来确定要服务的网站
-
原始配置的问题:使用
$host
会传递客户端的Host头(IP地址),导致Nginx尝试在本地解析 -
新配置的优点:明确指定
aimaji.top
确保请求被正确转发到目标域名
经验总结
-
日志是你的好朋友:遇到Nginx问题时,第一时间查看错误日志
-
理解Host头的作用:在代理配置中,Host头的设置至关重要
-
避免请求循环:确保代理不会将请求转发回自身
-
明确优于隐式:有时候明确指定值比使用变量更可靠
希望这篇记录能帮助遇到类似问题的开发者少走弯路!
发表评论
全部评论 (0)