Nginx反向代理域名但域名IP变化后还解析的是变化前的IP

之前有个测试环境配置 proxy_pass 时直接指定域名是可以用的,比如

location / {
    proxy_pass http://dev.abc.com:10068;
}

遇到一个问题是:
反向代理的地址是通过花生壳动态dns实现的。
dev.abc.com通过cname解析到花生壳之类的动态dns给分配的域名上,如果路由器因为断电或者掉线之类的原因重新拨号后ip发生变化,此处nginx就无法反向代理了,必须重启一次nginx才行。

报错如下图:

今天遇到一个问题就是通过 set 设置变量,然后 proxy_pass 调用变量实现反向代理(目的是减少配置复杂度),比如:

set $skyneturl "http://dev.abc.com:10077"; # 注意set好像不支持变量名中带下划线或其它特殊字符
 
location /applyrecord/aladinnApplyrecord { 
    proxy_pass $skyneturl;
}

重启nginx后发现报502错误,也就是连不上后端服务器。
看nginx日志发现错误提示:

2019/04/11 10:34:04 [error] 17241#0: *4334742 no resolver defined to resolve dev.abc.com ...

说没有定义 resolver命令 来解析域名,查了一下发现需要配置resolver参数。

官网文档:http://nginx.org/en/docs/http/ngx_http_core_module.html#resolver

Syntax: resolver address ... [valid=time] [ipv6=on|off];
Default:    —
Context:    http, server, location
 
Configures name servers used to resolve names of upstream servers into addresses, for example:

意思是需要配置dns地址用来再次解析upstream中的域名(用域名替代ip地址,后来经过测试upstream中配置域名只会在nginx启动时解析一次,然后就一直用这个ip,使用resolver实现每隔多久时时再次解析)
添加resolver配置参数:

#server里面设定示例
server {
    listen 8080;
    server_name localhost;
    resolver 202.102.134.68 114.114.114.114 valid=5 ipv6=off;
    resolver_timeout 3s;
    set $skyneturl "dev.abc.com"; 
    location /applyrecord/aladinnApplyrecord {
    	proxy_pass http://$skyneturl:10077;
    }
}

resolver:后接指定的DNS服务器,多个用空格隔开。resolver可以在http里面全局设定,也可以在server里面设定。
valid:DNS缓存时间,也可以不指定,缓存时间会默认根据域名的TTL时间。

ipv6:on或off,指定该域名解析为ipv6地址。
resolver_timeout:指定解析域名时,DNS服务器的超时时间,也可以不指定。
set :设置变量,在使用resolver之后,必须使用set设置变量来代替域名,否则会报错。另外,set不能写到 location里面否则不会生效。注意:set变量在server中可以设置成功,http中语法不允许。

#http里面设定示例
http{

    ......

    resolver 202.102.134.68 114.114.114.114 valid=5 ipv6=off;
    resolver_timeout 3s;
    
    server {
        listen 8080;
        server_name localhost;
        
        set $skyneturl "dev.abc.com"; 
        location /applyrecord/aladinnApplyrecord {
    	    proxy_pass http://$skyneturl:10077;
        }
    }

    ......

}

重启nginx后访问成功。


过程回顾:
无意间查资料发现 proxy_pass 后面跟域名的话并不是每次请求都会解析出这个域名的ip(这也验证了必须重启nginx才能解决),所以就会导致路由ip变化时造成服务无法访问。
解决这个问题的话,就可以用 set 设置一个变量,通过 resolver 实现每次访问都重新解析出ip地址。
这里还有一个问题,发现通过set和resolver设置域名解析时,重启路由器测试访问时,还是无法解析出新地址,通过tcpdump抓包没有发现有请求dns解析。
后来注意到还有个 valid 参数需要配置,这个参数用来控制缓存时间的,默认时间取决于dns记录的ttl值,比如我用windows搭建的dns解析默认是3600秒,也就是一小时。
通过修改valid参数,这里设置为5秒后,再次抓包发现每隔5秒后访问虚拟主机的时候就会产生一次dns解析。
在这里插入图片描述

这样才解决动态dns解析访问问题。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值