在使用nginx做反向代理的,将请求发送到一个动态DDNS域名的时候,该动态DDNS域名对应的IP是A ,刚开始运行一切正常,但是当运行了一段时间以后,该动态DDNS域名对应的IP变了之后(例如对应的IP由A变为B),nginx的转发仍然还在向原先的IP A发送请求,导致反向代理中断,此时reload nginx后才会重新恢复正常,且日志显示数据转发到新的IP B了,请问如何让nginx自动去重新解析域名,而不用每次出现问题了人工去reload?
造成这个问题的主要原因是,在Nginx启动的时候会做域名解析,然后把IP缓存起来以后会一直使用解析到的IP并且不会再更改,除非重新启动Nginx,Nginx才会重新解析域名。
第一种解决方案,利用nginx的resolver
1、默认nginx会通过操作系统设置的DNS服务器(/etc/resolv.conf)去解析域名
2、其实nginx还可以通过自身设置DNS服务器,而不用去找操作系统的DNS
3、下面来讲一个这个resolver示例配置如下:
server {
listen 8080;
server_name localhost;
resolver 114.114.114.114 223.5.5.5 valid=3600s;
resolver_timeout 3s;
location / {
proxy_pass http://mydomain.com;
}
}
参数说明:
# 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错误。
第二种解决方法——最佳解决方案是升级到tengine 2.1.2,淘宝出品的东西,已经自带了解决方案。
Tengine的模块ngx_http_upstream_dynamic_module,此模块提供了在运行时动态解析upstream中server域名的功能。
upstream backend {
dynamic_resolve fallback=stale fail_timeout=30s;
server a.com;
server b.com;
}
server {
…
location / {
proxy_pass http://backend;
}
}
(一)upstream的用法
1、upstream
作用:是用来定义服务器组的模块
使用范围:proxy_pass、fastcgi_pass、memcached_pass等
结构:
upstream groupName {server serverName1 [param1=value1] [param2=value2] [param3];server serverName2;}
groupName即为组名,是自定义的,如:upstream webserver;
2、server
upstream中的server用来指定一个服务器。
server的类型可以是:
- (1)域名:如:webserver.website.com;
- (2)IP:如:192.168.0.239:80;
- (3)Unix套接字文件:如unix:/tmp/webserver;
例如:
upstream webserver {server httpweb.withec.com;server 192.168.18.201 weight=5 max_fails=3 fail_timeout=20s;server 192.168.18.202 backup;server 192.168.18.293 down;server unix:/tmp/httpdweb;}
server中可用的参数:
- (1)weight:表示权重,权重越大,表示被访问的概率越大
用法:weight=数字;
server 192.168.18.201 weight=4;
- (2)max_fails:表示连接失败重新连接的最多次数
用法:max_fails=3;
如:
server 192.168.18.202 max_fails=3;
- (3)fail_timeout:连接超时的时间(即多久算连接失败)
用法:fail_timeout=时间;
如:20秒就算连接失败
server 192.168.18.202 max_fails=3 fail_timeout=20s;
- (4)backup:标记一台服务器作为备用服务器(它只在其他服务器繁忙的时候工作)
用法:server serverName backup;
如:
server 192.168.18.203 backup;
- (5)down:标记一台服务器下线或者暂时不可用
用法:server serverName down;
如:
server 192.168.18.203 down;
- (6)max_conns:表示指定的服务器最大连接数限制(nginx1.5.9以上版本才有的参数)
用法:max_conns=数字;
如:
server 192.168.18.202 max_conns=1024;
(二)、upstream实验:
4台机器:
- IP:192.168.18.200(作前端服务器)
- 192.168.18.201
- 192.168.18.202
- 192.168.18.203
步骤:
- 1、三台机器上的nginx都需要启动,并在各自web根目录下的index.html的文件中加入机器识别信息,具体如下:
- 200的机器上的index.html添加:from 200
- 201的机器上的index.html,添加:from 201
- 202的机器上的index.html,添加:from 202
- 203的机器上的index.html,添加:form 203
- 2、在237的机器上配置nginx(1)在http块中加入:
upstream webserver {server 192.168.18.201:80;server 192.168.18.202:80;server 192.168.18.203:80;}
(2)在server区段的location段加入:
location / {proxy_pass http://webserver;}
注:webserver这个组名前一定要记住加http://
打开浏览器访问:http://192.168.18.200,查看显示内容
- 发现显示”from 201”
- 刷新显示”from 202”
- 再刷新显示”from 203”
- 再刷新显示””from 201
依次刷新会在这三台机器之间循环(这种专业的叫法叫轮询)
(三)upstream模块主要指令
- 1、hash:指定轮询的规则按照指定的key值来计算
用法:hash key;
这个key可以包含文本,变量或者文本与变量的组合。
- 2、ip_hash;指定轮询的规则按照ip的hash值来计算
针对上面的实验:我们在upstream中加入ip_hash,再查看:
发现我们无论怎么刷新,访问的都是201上面的文件(因为客户端的IP没变)