一般情况下,我们使用nginx反向代理到后端用的是ip或者地址池。例如
location /api { proxy_pass http://192.168.150.100:8000/api; }
或者
upstream myserver { server 192.168.150.100:8000; #APP1 ip:port server 192.168.150.101:8000; #APP1 ip:port server 192.168.150.102:8000; #APP3 ip:port } ...... location /api { proxy_pass http://myserver/api; proxy_set_header Host $http_host; }
这种情况不存在nginx缓存问题
但是有时候我们也会反向代理到域名上
location /api { proxy_pass http://www.test.com:8000/api; }
在我之前做的一个项目上就这样做过,域名通过GTM解析,分发流量。而且最开始成功了,并没有问题。但是在某次www.test.com域名指向的两台服务器挂了一台之后,整个服务就出现问题,访问不了。看日志nginx对www.test.com解析一直只指向一台服务器。
重启nginx之后,访问才恢复正常。
查阅资料之后对于代理反向指向域名的这种方式,nginx只会根据启动时从服务器获取的解析IP进行代理,直到下一次nginx重启,或者reload。这样一来其实GTM的流量分发并没有意义,并且服务架构还存在隐患。
那么如何让nginx实时解析反向代理的域名呢?
可以使用nginx的resolver。示例如下
server { listen 8080; server_name localhost; resolver 114.114.114.114 223.5.5.5 valid=60s; resolver_timeout 3s; set $test "www.test.com"; location /api { proxy_pass http://$test; } }
说明:
resolver:后接指定的DNS服务器。多个用空格隔开。resolver可以在http里面全局设定,也可以在server里面设定。
valid:DNS缓存时间。也可以不指定,缓存时间会默认根据域名的TTL时间
resolver_timeout:指定解析域名时,DNS服务器的超时时间
set :设置变量。在使用resolver之后,必须使用set设置变量来代替域名。否则会报错。另外,set不能写到 location里面否则不会生效。