Nginx的DNS缓存问题
在使用Nginx作为反向代理服务器时,有时会遇到DNS缓存问题,导致后端服务IP变化后就无法访问,本文介绍一下如何处理这个问题。
问题场景
下面是一个常见的Nginx配置示例:
在这个示例中,Nginx会监听 qzy.im
域名上的 80
端口,然后将路径下的所有请求都转发到 http://some-domain.qzy.im
上。如果域名 some-domain.qzy.im
的IP不会发生变化,那么上面的配置就不会出现问题。
但是,如果 some-domain.qzy.im
的IP是会变化的,那么一旦IP发生变化,服务就无法访问了,这是为什么呢?
问题原因
问题就出在Nginx的DNS缓存上。正常情况下,如果 proxy_pass
后指定的主机使用的是域名,那么Nginx就只会在载入配置的时候解析一次该域名对应的IP,后续请求都会发到这个IP上。即使该域名的IP发生了变化,Nginx也不会向新的IP上转发请求。
解决办法一
如果指定域名的IP变化频率很低,或者说只有人为解析会导致IP变化,那么就可以使用这个最简单的办法。IP变化后执行命令,让Nginx重新加载配置文件即可:
解决办法二
如果指定域名的IP变化的频率高,那么解决办法一就很麻烦,这个时候就可以使用这个办法。Nginx提供了设置DNS缓存过期时间的功能,配置方式如下:
上面第1行代码用来配置DNS服务器和缓存过期时间,第2行将需要转发的主机地址设置到一个变量中,最后第3行就实现代理转发。我们将问题场景中的配置改成如下:
这样,每次通过 proxy_pass
转发请求前,Nginx就会检查 some-domain.qzy.im
的DNS是否过期(上面设置的过期时间值 valid
是10s),如果过期了Nginx就会从DNS服务器获取最新的IP,然后再进行转发。
注意:必须通过一个变量(例如上面的 $host_name
)来设置代理,如果直接写成 proxy_pass <主机地址>
,则Nginx只会在载入配置的时候解析一次,后面就不会自动刷新了。
参考资源
https://nginx.org/en/docs/http/ngx_http_core_module.html#resolver
https://www.nginx.com/blog/dns-service-discovery-nginx-plus/