nginx 配置中有1个upstream配置是指向一个域名Y的,而这个域名Y解析对应IP其实是会动态变化的。
今天的生产遇到一个很奇怪的现象,一个代理到 cdn 的静态资源访问超时了。 去查看了 nginx 的配置:
location /xxxx.js {
proxy_set_header Host cdn.com;
proxy_pass https://cdn.com/platform/xxx.js;
}
单独访问 https://cdn.com/platform/xxx.js 没问题。但是生产系统的域名访问,走了代理之后,这个资源就超时了。看了 nginx 的 access.log 发现 DNS 解析到的 IP 对应的机器访问不了了。后来跟运维了解到是这个 IP 对应的机器节点下线了。
而由于生产机器上的 nginx DNS 有缓存,导致解析到的还是这个失效的 IP。
提示:nginx本身有dns缓存机制,配置文件中 resolver 配置了dns的valid时间是10天。对于nginx 的 dns 缓存来说,nginx会在首次proxy_pass到upsteam时并且upstream是域名配置的,nginx就会解析域名,并缓存直到valid时间后,再重新重新解析dns的结果。
这样来看的话,如果我们想要把域名Y后面对应的服务器S退出的话,比较合理的做法应该是让已经退休的S运行一段时间,在开一台新的服务器S2,把域名Y解析到S2上。但是至少要保证原来的S能够正常运行足够久的时间T。这样所有的客户端,才可以正常访问服务。
这样问题就清楚了。
nginx -s reload
就能解决上面的问题。
resolver的语法如下:
Syntax: resolver address ... [valid=time] [ipv6=on|off];
Default: —
Context: http, server, location
可以配置多个dns服务,nginx会采用轮询的方式去访问dns服务,nginx会缓存dns对域名解析的结果,缓存的时间由valid指定,ipv6用于显示开启或者关闭ipv6。
Syntax: resolver_timeout time;
Default:
resolver_timeout 30s;
Context: http, server, location
resolver_timeout用于指定dns解析的超时时间。