一直学一直嗨,一直嗨一直学

nginx使用DDNS域名作为反向代理的upstream

文章目录

[隐藏]

  • 0x01 前言
  • 0x02 BUG
  • 0x03 DEBUG
  • 0x04 结语
0x01 前言

我配置所有的服务都喜欢在前面套一个nginx,然后加上SSL以保安全。在这过程中有一种情况比较特殊,就是upstream使用DDNS进行解析。

正好前两天发现有位V友也问了这个问题,在解答之后我将这个问题记录在这里,V站链接如下:

https://www.v2ex.com/t/387350#reply15

这种使用方式也挺常见的,例如后端放在家里或其他没有固定IP的网络中,又需要将这个服务暴露在公网,可是不希望每次访问都输入端口号,这时候就需要反向代理。

0x02 BUG

nginx的反向代理需要配置一个upstream,而upstream支持众多协议,这里以http协议为例:

[root@web conf.d]# cat zabbix.t.com.ngx.conf  server {        listen                  80;      server_name             zabbix.t.com;        root                    /usr/local/services_data/html/zabbix.t.com/public_html/;        access_log              /usr/local/services_data/html/zabbix.t.com/logs/ngx_access.log;        location / {            index               index.php index.html;          proxy_pass          http://127.0.0.1:8080;        }    }  

以上是我家zabbix作为后端,nginx作为前端的配置文件,其中proxy_pass使用http协议访问127.0.0.1:8080这个后端地址。

以上配置一般不会出现问题,如果后端的IP地址出现了变更,那么就需要手动修改nginx的配置文件并reload。

如果proxy_pass使用了域名,如下:

proxy_pass http://zabbix-upstream.t.com:8080;  

而且这个域名使用DDNS动态解析的方式,就会有一个问题:

nginx只会在nignx启动的时候解析域名并缓存,如果域名的解析变了,nignx也不会有任何动作。

这样会导致这个服务再也无法访问。

0x03 DEBUG

解决方法很简单,只需要将proxy_pass部分做一些改造:

server {  ...  resolver [DNS IP 地址] valhttp://ddns.domain.com:4430";  proxy_pass $[变量名];  ...  }  

例如:

server {  ...  resolver 114.114.114.114 valhttp://ddns.domain.com:4430";  proxy_pass $upstream;  ...  }  

这里用了set变量这种方式,使用set这种指定变量的方式有一个特点:每次访问都会出发 {} 符号内的set。

这也就是说,每次访问都对运行一遍set。

而上面的proxy_pass配置会强制每一次访问都进行解析,同时使用resolver参数指定DNS和TTL。

resolver参数所指定的TTL优先级最高,可以覆盖DNS的TTL。如果DNS默认的TTL为60s,那么上面的配置会将TTL修改为5s。

这里还有个需要注意的地方,如果不是必要,不要再server段设定set,这在大流量的情况下会引发性能下降,如果可以,将set放置在location段会更好。

0x04 结语

问题解决,如果不是使用DDNS解析的域名作为upstream,请不要使用上述方法配置proxy_pass。另外要尽量减少set变量。

原文出处:enginx -> https://enginx.cn/2017/09/03/nginx%E4%BD%BF%E7%94%A8ddns%E5%9F%9F%E5%90%8D%E4%BD%9C%E4%B8%BA%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86%E7%9A%84upstream.html

Tags:,