Nginx 把 proxy_pass 改成变量后返回 502:no resolver defined to resolve
固定域名代理正常,改成变量后 502:配置可解析内部域名的 resolver,并核对变量形式是否改变了接口路径。
后端域名直接写在 proxy_pass 里时代理正常,改成变量后却出现 502 Bad Gateway,错误日志包含 no resolver defined to resolve。这时优先检查 Nginx 的运行时 DNS 配置;应用超时和连接池参数通常不能解决这个报错。
这里讨论普通 HTTP 代理:变量展开后的目标是域名,而且没有命中已有的命名 upstream 组。IP 地址目标以及命名 upstream 组的情况不完全相同。
为什么系统能解析,Nginx 仍说没有 resolver
下面是触发条件的配置示例,域名与路径需要换成自己的后端:
location /myapi {
set $api_origin http://api.internal.example:80;
proxy_pass $api_origin/myapi;
}
没有变量的固定域名通常在配置加载阶段解析。使用变量后,Nginx 会先查找对应的 upstream 组;找不到时,需要通过 resolver 在请求阶段解析域名。操作系统解析配置可用,不等于这条运行时解析路径已配置。
检查错误日志时,区分 no resolver defined、域名无法解析和 connect() failed。第一种说明尚未指定解析器;第二种需要检查指定 DNS 是否可达、是否知道这个内部域名;第三种则已经进入连接后端的阶段。
指定能解析内部域名的 DNS
在对应的 http、server 或 location 范围内配置 resolver。以下是结构示例,10.0.0.53 必须替换为 Nginx 所在网络能访问、并且能解析后端名称的受控 DNS:
resolver 10.0.0.53;
resolver_timeout 5s;
location /myapi {
set $api_origin http://api.internal.example:80;
proxy_pass $api_origin;
}
容器和 Kubernetes 服务名经常只有内部 DNS 知道。随手填公共 DNS,可能把报错变成“找不到域名”。同样,宿主机上的 127.0.0.53 不一定能被容器访问:容器里的回环地址指向容器自身。
DNS 地址要从实际运行环境确定,不按教程复制。修改前保留原配置,先检查配置,再用该实例实际采用的方式重载;重载影响后续代理请求,异常时恢复原配置并重新检查、重载。默认安装的检查命令示例是:
nginx -t
使用容器或非默认配置文件时,应针对同一个 Nginx 实例检查。单纯配置检查通过,还不能证明 DNS 服务器可达或后端可连接。
解析恢复后,再确认接口路径没有丢失
变量形式还会改变带 URI 的 proxy_pass 行为。上面的错误示例写成 $api_origin/myapi,会把指定的 /myapi 作为上游 URI;访问 /myapi/orders?limit=10 时,不能继续依赖固定域名写法的前缀替换规则。
如果后端本来就接受完整的 /myapi/orders?limit=10,示例中的 proxy_pass $api_origin; 不附加 URI,便保留原请求路径及查询参数。若后端需要去掉 /myapi 前缀,应另外明确重写目标,并核对路径和查询参数,不能只往变量后加一个 /。
成功标准是:日志中不再出现缺少解析器的错误,后端收到预期接口路径和查询参数,并返回正常业务响应。若 502 消失但接口变成 404,查看后端收到的 URI,比继续修改 DNS 更有用。


