Ubuntu 22.04 上 nginx 1.18 做反向代理,proxy_pass 写成了变量形式,后端域名解析换过 IP 之后业务仍然打到旧机器,curl 直连新域名是对的。
一开始怀疑是「upstream 里写的是 IP,proxy_pass 里的域名根本没参与解析」,查了一圈,方向不对。
这类报错背后常见的原因有几处,逐个排除就行。proxy_pass 里带变量时 nginx 不做启动期解析,改用运行时 resolver 查,但没配 resolver 就只认启动缓存。另一种情况是配了 resolver 但没有 valid 参数,解析结果按 TTL 缓存,域名 TTL 被设成了 3600。
不容易想到的是,reload 只重载配置,进程内的解析缓存要等过期。
动手时先确认 proxy_pass 是不是变量形式
nginx -T | grep -n 'proxy_pass'
补上 resolver 和短缓存时间
printf 'resolver 100.100.2.136 valid=10s;\n' > /etc/nginx/conf.d/resolver.conf
接着用变量形式并显式发出域名
nginx -T | grep -A2 'set \$backend'
reload 后观察后端连的是哪个 IP
nginx -s reload && ss -tnp | grep nginx | head
别只看报错消失,验证要多做一步。reload 之后 ss 里 nginx 到后端的连接落在新 IP 上,业务日志不再出现旧机器的特征,解析结果十秒内更新。
这里还有个坑。变量形式的 proxy_pass 会绕开 upstream 的健康检查,建议还是用 upstream 加 resolve 参数;resolver 一定要配 valid,默认缓存时间比你想象的久。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。
