关键在于显式配置resolver指令:在http块中指定多个dns服务器(如114.114.114.114 8.8.8.8)、设置valid=5s启用短时缓存、配合resolver_timeout 3s防阻塞,并通过变量proxy_pass实现每次请求动态解析,确保及时获取上游最新ip。

关键在于让 Nginx 主动、及时、可靠地获取上游域名的最新 IP,而不是依赖静态缓存或系统默认解析。DNS 解析卡顿或过期,直接导致 502 错误、连接超时或流量打到下线节点。
明确配置 resolver 指令
Nginx 默认不内置 DNS 解析器,也不自动读取 /etc/resolv.conf。必须在 http 块中显式声明:
- 用 resolver 指定至少两个可靠的 DNS 服务器,例如:
resolver 114.114.114.114 8.8.8.8 valid=5s; - valid=5s 表示 DNS 缓存最多保留 5 秒,适合后端服务频繁扩缩容或 DNS 轮询调度的场景
- 避免只写一个 DNS 地址,主 DNS 故障时会阻塞解析;多地址可自动故障转移
- 不要把 resolver 放在 server 或 location 块里——它只在 http 级生效
配合变量使用实现动态解析
直接写 proxy_pass http://api.example.com 是静态解析,Nginx 启动时只查一次。要真正“动态”,必须结合变量:
- 在 location 中用 set $backend "api.example.com";
- 再写 proxy_pass http://$backend;
- 这样每次请求都会触发 resolver 重新查 DNS,而非复用启动时的 IP
- 注意:proxy_pass 后不能带 URI 路径(如 http://$backend/),否则变量解析会失效
控制解析超时与重试行为
DNS 查询本身可能慢或失败,需主动设限:
- 添加 resolver_timeout 3s;,防止 DNS 查询卡住整个请求周期
- 搭配 proxy_next_upstream error timeout http_502;,当后端因 DNS 失效无法连接时,可尝试下一个 upstream(如有多个)
- 若使用 upstream 块,确保每个 server 行用域名而非 IP,并开启 resolve 参数(需编译时含 ngx_http_upstream_resolve_module)
监控与验证是否生效
光配对不等于跑对,建议做三件事确认:
- 检查 Nginx 错误日志:grep "resolver" /var/log/nginx/error.log,看有无 "no resolver defined" 或超时告警
- 手动触发一次 DNS 变更(如改 DNS 记录 TTL 为 1s,更新 IP),观察 access 日志中请求是否在几秒内转向新地址
- 用 nginx -t 验证语法,重启后执行 ss -ant | grep :53,确认 Nginx 进程确实在向你指定的 DNS 发起查询











