遇到 Nginx 反向代理报域名解析失败,核心原因通常是缺少 resolver 配置或 DNS 服务器不可达。但需注意,仅在配置中添加 resolver 并不一定能实现域名动态刷新,关键在于 proxy_pass 是否使用了变量。
先说结论:Nginx 无法解析 upstream 域名时,需显式配置 DNS 服务器。若需运行时动态刷新 DNS,必须在 proxy_pass 中使用变量配合 resolver。
- 检查 error.log 确认报错关键字
- 区分静态 upstream 与动态变量解析场景
- 配置 resolver 并验证解析生效
命令速用版
快速定位是否为 DNS 问题,按顺序执行:
# 1. 测试本机 DNS 是否正常
dig example.com
# 2. 查看 Nginx 错误日志
tail -n 50 /var/log/nginx/error.log
# 3. 检查 Nginx 配置语法
nginx -t
# 4. 重载配置
nginx -s reload核心机制:静态与动态解析的区别
这是最容易混淆的地方。Nginx 对域名的解析行为取决于配置方式:
1. 静态 upstream 配置
如果在 upstream 块中直接写域名,Nginx 仅在启动或重载配置时解析一次。即使配置了 resolver 指令,也不会定期刷新该域名的 IP。若上游 IP 变更,必须 reload Nginx 才能生效。
2. 动态变量配置
如果在 proxy_pass 中使用变量(如 http://$host),Nginx 会在运行时查询 DNS。此时必须配置 resolver 指令,否则报错 host not found。这种方式支持按 valid 参数定期刷新 DNS。
分步处理与配置示例
第一步:确认报错类型
打开错误日志,搜索 resolver 或 host not found。若看到 upstream timed out 通常是网络连通性问题,而 host not found in upstream 明确指向解析失败。
第二步:配置 resolver 指令
在 http 或 server 块中加入 resolver 指令,指向可靠的 DNS 服务器。注意 valid 参数控制缓存时间。
http {
# 配置 DNS 服务器,缓存 30 秒
resolver 8.8.8.8 valid=30s;
server {
location / {
# 动态解析示例
set $upstream_host example.com;
proxy_pass http://$upstream_host;
}
}
}第三步:检查上游定义
如果必须使用 upstream 块(如负载均衡),请知晓域名仅在启动时解析。若需动态刷新,建议改用变量形式的 proxy_pass,或在脚本中监控 DNS 变化后 reload Nginx。
第四步:重载服务
修改配置后,务必先执行 nginx -t 检查语法,确认 successful 后再执行 reload。避免直接 restart 导致服务中断。
怎么验证是否生效
配置重载后,观察错误日志是否不再出现解析报错。同时模拟请求检查响应:
curl -I http://你的 Nginx 地址若返回 200 状态码且日志无新错误,说明修复成功。若仍报错,检查 resolver 指向的 DNS 服务器是否被防火墙拦截。
常见坑
1. 变量必须配 resolver:只要 proxy_pass 里用了变量,就必须配 resolver,否则 Nginx 无法在运行时解析域名。
2. 静态 upstream 不刷新:upstream 块中的域名不会因 resolver 配置而自动刷新 IP,仅启动/重载时解析。需动态刷新请使用变量方案。
3. 启动时解析失败:如果 upstream 里写域名,Nginx 启动时会解析一次。如果当时 DNS 不通,启动会失败。确保启动前 DNS 正常。
参考来源
- Nginx 官方文档 - resolver 指令说明,URL: https://nginx.org/en/docs/http/ngx_http_core_module.html#resolver
- Nginx 官方文档 - proxy_pass 指令说明,URL: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass