一聚教程网:一个值得你收藏的教程网站

热门教程

Nginx 中 Upstream 如何排查因 DNS 缓存未更新导致的后端失联故障

时间:2026-08-28 20:15:49 编辑:袖梨 来源:一聚教程网

核心是确认Nginx是否使用过期IP:日志中upstream后显示的IP若与dig结果不一致,即为DNS缓存问题;原生upstream不支持动态解析,须改用变量+resolver、resolve参数或第三方模块。

排查 upstream 因 DNS 缓存未更新导致的后端失联,核心是确认 Nginx 当前连接的 IP 是否已过期——它不看系统能否解析,而看 Nginx 实际发往哪个地址。

查 error.log 里 upstream 真实连接目标

打开 /var/log/nginx/error.log,搜索以下关键词:

  1. upstream timed outconnect() failed
  2. 重点看日志中 upstream: 后面的地址,例如:upstream: "http://10.20.30.40:80/"
  3. 立即在终端执行:dig your-backend-domain.com +short,比对返回的 IP 是否与日志中一致
  4. 不一致,说明 upstream 正在用过期 IP,就是 DNS 缓存问题

确认 upstream 块是否支持动态解析

原生 upstream 不支持运行时 DNS 刷新。只要写成这样:

upstream backend {

server api.example.com:80;

}

就代表 Nginx 只在启动或重载时解析一次,之后永不更新。解决路径只有三种:

  1. 升级到 Nginx ≥1.19 并启用 resolve 参数(需配合顶层 resolver
  2. 改用 proxy_pass + 变量模式(放弃 upstream 结构,用 set $upstream "api.example.com"; proxy_pass http://$upstream;
  3. 引入第三方模块如 nginx-upstream-dynamic-servers,支持 server api.example.com resolve;

验证 resolver 配置是否真正生效

即使写了 resolver,也必须满足两个条件才起作用:

  1. resolver 必须出现在 httpserverlocation 块中(不能只写在 stream 模块却用于 http 流量)
  2. proxy_pass 必须引用变量,而非直写域名;upstream 中的 server 行加 resolve 才会触发 resolver
  3. 在 Nginx 机器上手动测试:nslookup api.example.com 8.8.8.8,确认 DNS 服务器可达且返回正确 IP
  4. 检查 nginx -T | grep resolvernginx -T | grep proxy_pass,确认配置被加载且没被静态展开为 IP

临时绕过并快速验证根因

不重启、不改配置也能快速锁定问题:

  1. 在 Nginx 所在机器的 /etc/hosts 中添加一行:1.2.3.4 api.example.com(填当前正确的后端 IP)
  2. 执行一次 curl -I http://your-nginx-domain/api,若立刻恢复,基本坐实是 DNS 缓存问题
  3. 再删掉 hosts 条目,等待 valid=30s 过期后重试,观察错误是否重现
  4. 同时用 ss -tnp | grep :8080 查看 worker 进程当前连的是哪个 IP,对比是否随 DNS 变更而更新

热门栏目