全球主机交流论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

CeraNetworks网络延迟测速工具IP归属甄别会员请立即修改密码
查看: 4193|回复: 7

nginx的dns缓存问题----貌似是解决nginx反代ddns的一个问题

[复制链接]
发表于 2018-4-17 08:41:02 | 显示全部楼层 |阅读模式
本帖最后由 t9913085 于 2018-4-17 08:44 编辑

如题,使用nginx做反向代理,将请求发送到一个域名(例如: proxy_pass http://www.test.com  该域名对应的IP是A) ,刚开始运行一切正常,但是当运行了一段时间以后,域名对应的IP变了(例如http://www.test.com对应的IP由A变为B),nginx的转发仍然还在向原先的IP发送请求,导致业务中断,此时reload nginx后才会重新恢复正常,且日志显示数据转发到新的IP B了,请问如何让nginx自动去重新解析域名,而不用每次出现问题了人工去reload? 请大神指点

作者:黑板擦
链接:https://www.zhihu.com/question/61786355/answer/268735267
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

时隔几个月,遇到了其他问题,忽然找到了解决这个问题的方法,现在分享一下背景:此处只针对nginx向后端做代理,且后端代理为域名形式 的这种情况做分析

1、正常情况下 启动nginx后(或者 -t / reload nginx时),nginx会通过操作系统配置的DNS服务器去解析域名对应的IP

2、当nginx配置文件中的所有涉及到的域名都可以被正常解析到以后,才能启动(或者检查/重新加载)通过

3、这里需要提醒一点,在 ../sbin/nginx -t 或者 ../sbin/ngins -s reload 只是检查域名是否可以解析通过,并不会在此时缓存域名对应IP,只有在通过nginx第一次向proxy_pass后端对应的域名做代理数据转发时,这里nginx会通过操作系统配置的DNS服务器解析域名,此时才会缓存域名对应的IP,且会缓存很长时间,甚至一个月(整个过程均有生产实例证明,且抓包验证)

我遇到的问题:

生产的实例

1、我们内网的数据通过nginx转发到第三方合作公司对应的域名,此处简称为 域名A

2、第三方公司的域名A做了CDN,对应多个IP(IP1,IP2,IP3...),且随时都有可能因某种原因,丢弃其中一个IP

3、某一天该第三方公司将他们的域名A对应的地址IP3废弃不用了,域名不再往IP3上解析了

4、但是我们的nginx因为曾经请求域名A时缓存了IP3,导致后续的许多交易数据仍旧是给IP3发送,造成交易失败,这种情况在我们没有reload nginx之前,存在了2周左右,说明nginx缓存这个IP3缓存了很长时间,这就是造成了我们交易失败的原因(当时排查了好几天),后来多方联系核对后,才知道第三方公司早在3周前就废弃了这个IP3,(可能为了全网的DNS都刷新,域名A不再向IP3解析后,但是IP3所对应的服务器还继续沿用了一段时间,所以我们是在废弃后的第二周才开始报错)

分析与解决:

1、既然是因为nginx缓存域名对应IP的DNS记录造成的,那么怎么才能解决呢,方法有两种:

(1)、手动reload nginx,让nginx重新解析域名,这个时候解析到域名对应的IP是最新的,不会包含已经被废弃的IP3

(2)、设置nginx的DNS缓存时间,比如600s失效,然后重新去解析

2、方法(2)当然是最好的,但是nginx的DNS缓存时间在哪里设置呢,我没有找到!

3、但是我找到另外一种方法 -- nginx 的 resolvernginx的resolver

解决方案

1、默认nginx会通过操作系统设置的DNS服务器(/etc/resolv.conf)去解析域名

2、其实nginx还可以通过自身设置DNS服务器,而不用去找操作系统的DNS

3、下面来讲一个这个resolver示例配置如下:

  1. server {
  2.        listen      8080;
  3.        server_name localhost;
  4.        resolver 114.114.114.114 223.5.5.5 valid=3600s;
  5.        resolver_timeout 3s;
  6.        set $qq "**";
  7.        location / {
  8.           proxy_pass http://$qq;
  9.        }
  10.    }
复制代码


参数说明:

# resolver 可以在http全局设定,也可在server里面设定
# resolver 后面指定DNS服务器,可以指定多个,空格隔开
# valid设置DNS缓存失效时间,自己根据情况判断,建议600以上
# resolver_timeout 指定解析域名时,DNS服务器的超时时间,建议3秒左右

#注意:当resolver 后面跟多个DNS服务器时,一定要保证这些DNS服务器都是有效的,因为这种是负载均衡模式的,当DNS记录失效了(超过valid时间),首先由第一个DNS服务器(114.114.114.114)去解析,下一次继续失效时由第二个DNS服务器(223.5.5.5)去解析,亲自测试的,如有任何一个DNS服务器是坏的,那么这一次的解析会一直持续到resolver_timeout ,然后解析失败,且日志报错解析不了域名,通过页面抛出502错误。

#重点:如上例,在代理到后端域名http://**时,千万不要直接写在proxy_pass中,因为server中使用了resolver,所以必须先把域名定义到一个变量里面,然后在 proxy_pass http://$变量名,否则nginx语法检测一直会报错,提示解析不了域名

后记

整个过程亲测,没有问题如果有其他更好的方式或者见解,请回复一起探讨哈

http://nginx.org/en/docs/http/ngx_http_core_module.html

发表于 2018-4-17 09:23:53 | 显示全部楼层
学习了,没想到nginx还会缓存域名解析结果
发表于 2018-4-17 09:27:23 来自手机 | 显示全部楼层
我也遇到这个问题了,后来脚本定时获取ip,只要有变动,就杀掉nginx进程,重新开启
发表于 2018-4-17 09:29:42 来自手机 | 显示全部楼层
哇。认真的看完了。原来nginx还有这种问题。
发表于 2018-4-17 09:33:59 | 显示全部楼层
前排跟着大佬学姿势
发表于 2018-4-17 09:35:33 | 显示全部楼层
一般来说都是对应后面ip.重新启动一下nginx 就解决。
发表于 2018-4-17 09:49:36 来自手机 | 显示全部楼层
我觉得更可取的方法是在upstream里配置三个后端然后做health check,用dns来做负载均衡的话,不知道选的是哪个ip,很难定位问题。提示无法解析的那个问题可以用http级别的resolver解决,因为解析到proxy pass时不会用到server级别的resolver配置,所以导致无法解析。实际上之所以这样能重新解析是因为用了变量来配置后端,而用变量就必须配置一个resolver,而不是用了resolver所以会重新解析。
发表于 2018-4-17 09:51:27 | 显示全部楼层
插旗,不知道还有这样的解决方案。
其实我之前一直用另一种解决方案:换tengine。
某宝出品的东西,已经自带了解决方案。
http://tengine.taobao.org/document_cn/http_upstream_dynamic_cn.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|全球主机交流论坛

GMT+8, 2025-9-19 05:28 , Processed in 0.067744 second(s), 8 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表