nginx的dns缓存问题

https://www.zhihu.com/question/61786355

如果是转发给K8S域名,使用如下配置:
server {
listen 7777;

resolver 8.8.8.8 valid=60s;
location ~* /base/(.*) {
set b a s e w e b h o s t " k 8 s − c o s m o m e s − b a s e w 2. a p − s o u t h − 1. e l b . a m a z o n a w s . c o m " ; p r o x y i g n o r e c l i e n t a b o r t o n ; p r o x y p a s s h t t p : / / basewebhost "k8s-cosmomes-basew2.ap-south-1.elb.amazonaws.com"; proxy_ignore_client_abort on; proxy_pass http:// basewebhost"k8scosmomesbasew2.apsouth1.elb.amazonaws.com";proxyignoreclientaborton;proxypasshttp://basewebhost/base/ 1 1 1is_args$args;
}
}

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

时隔几个月,遇到了其他问题,忽然找到了解决这个问题的方法,现在分享一下背景:此处只针对nginx向后端做代理,且后端代理为域名形式 的这种情况做分析1、正常情况下 启动nginx后(或者 -t / reload nginx时),nginx会通过操作系统配置的DNS服务器去解析域名对应的IP2、当nginx配置文件中的所有涉及到的域名都可以被正常解析到以后,才能启动(或者检查/重新加载)通过3、这里需要提醒一点,在 …/sbin/nginx -t 或者 …/sbin/ngins -s reload 只是检查域名是否可以解析通过,并不会在此时缓存域名对应IP,只有在通过nginx第一次向proxy_pass后端对应的域名做代理数据转发时,这里nginx会通过操作系统配置的DNS服务器解析域名,此时才会缓存域名对应的IP,且会缓存很长时间,甚至一个月(整个过程均有生产实例证明,且抓包验证)我遇到的问题:生产的实例1、我们内网的数据通过nginx转发到第三方合作公司对应的域名,此处简称为 域名A2、第三方公司的域名A做了CDN,对应多个IP(IP1,IP2,IP3…),且随时都有可能因某种原因,丢弃其中一个IP3、某一天该第三方公司将他们的域名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、但是我找到另外两种方法 (1)、upstream的max_fails + fail_timeout参数(2)、nginx 的 resolver解决方案1:upstream 的max_fails + fail_timeout参数10s内,失败3次,则不再往故障IP发生请求,根据自身情况调整参数upstream backends {
least_conn;
server backends.example.com:8080 max_fails=3 fail_timeout=10s;
}

server {
location / {
proxy_pass http://backends;
}
}解决方案2:nginx的resolver 1、默认nginx会通过操作系统设置的DNS服务器(/etc/resolv.conf)去解析域名2、其实nginx还可以通过自身设置DNS服务器,而不用去找操作系统的DNS3、下面来讲一个这个resolver示例配置如下:server {
listen 8080;
server_name localhost;
resolver 114.114.114.114 223.5.5.5 valid=3600s;
resolver_timeout 3s;
set KaTeX parse error: Expected '}', got 'EOF' at end of input: …xy_pass http://qq;
}
}参数说明:# 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://www.qq.com时,千万不要直接写在proxy_pass中,因为server中使用了resolver,所以必须先把域名定义到一个变量里面,然后在 proxy_pass http://$变量名,否则nginx语法检测一直会报错,提示解析不了域名后记整个过程亲测,没有问题如果有其他更好的方式或者见解,请回复一起探讨哈

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值