平滑重载(nginx -s reload)不会刷新 DNS 缓存,因 Nginx 默认对写死域名仅静态解析一次;必须用变量+resolver指令(如set $backend "api.example.com"; proxy_pass http://$backend;)并确保作用域匹配,才能实现按valid时限动态解析。

平滑重载(nginx -s reload)本身不会刷新 DNS 缓存——这是 Nginx 的设计特性,不是故障。只要 proxy_pass 写死域名(如 http://api.example.com),Nginx 就只在首次连接时解析一次 IP 并长期缓存,reload 不会触发重解析。排查重点不是“为什么没刷新”,而是确认是否本就未启用动态解析机制。
看错误日志里有没有 DNS 解析行为
执行 tail -f /var/log/nginx/error.log,观察真实请求过程:
- 若出现
resolving "api.example.com"后紧跟resolved to 10.20.30.40:说明 resolver + 变量模式已生效,DNS 正在按valid=周期刷新 - 若只有
upstream timed out (110) while connecting to upstream, upstream: "http://10.10.10.114:80/",且 IP 长期不变:说明仍是静态解析,reload 没起作用,配置未启用动态能力 - 若出现
resolver timeout或no resolver defined:说明resolver指令缺失、位置错误(如只写在 location 里),或 DNS 服务器不可达
检查 proxy_pass 是否真的用了变量
运行 nginx -T | grep 'proxy_pass' 查看实际展开结果:
- 输出中显示
proxy_pass http://$backend;或类似变量引用:正确,走的是运行时解析路径 - 输出中直接显示
proxy_pass http://api.example.com:8080;:即使配置写了resolver,也无效;必须改成set $backend "api.example.com:8080"; proxy_pass http://$backend; - 注意:变量必须在
location块内定义,且不能是空值或拼写错误(如$backent)
验证 resolver 配置是否在有效作用域
resolver 必须出现在 http、server 或 location 块中,且需覆盖到使用变量的 proxy_pass 所在位置:
- 推荐统一放在
http块顶层,避免遗漏:http { resolver 223.5.5.5 114.114.114.114 valid=30s timeout=5s; } - 若只写在某个
server块里,而proxy_pass在子location中用变量,则仍有效;但若写在location里,部分旧版本 Nginx 可能不识别 - 确认没被注释、没拼错(如写成
reslover),且 DNS 地址能从 Nginx 所在机器连通(ping 223.5.5.5或dig @223.5.5.5 api.example.com)
对比 reload 前后连接目标是否变化
用系统命令直接观察 worker 进程实际连向哪个 IP:
- reload 前执行:
ss -tnp | grep ':8080' | awk '{print $5}' | sort -u,记下旧 IP - 手动更新后端 DNS(如改
api.example.com到新 IP),等待超过valid=30s后再发请求 - reload 后再执行同样命令,看是否出现新 IP —— 若仍是旧 IP,说明根本没走 resolver 动态路径
- 注意:要等 DNS 生效且 Nginx 主动触发解析(即有新请求进来),空等 reload 不会主动刷新


















