修改Nginx的配置,如下:
server { ...... location / { proxy_pass :5555; # 改成域名 proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; # 还原为60秒 } ...... }启动后端程序,然后用浏览器访问看看可以正常访问页面,如果愿意还可以修改Python程序中的sleep时间,改成0,我们这个测试对于后端响应时间没有要求。
这时候你把/etc/hosts中添加的那个解析记录删除,你再次访问,会发现还可以访问到页面内容,而且Nginx日志里都是正常的。
下面则是最关键的,你把运行flask程序的主机也就是192.168.10.50这个主机IP修改为60(总之就是和之前不一样):
然后再次用浏览器访问,你觉得会发生什么?肯定还是访问不到,看看日志:
你可以看到错误日志和情况一是一样的,但是场景不同了。有人说我把HOST注释了,其实你就是把解析记录修改为新的IP地址其结果也是一样的。这是因为Nginx自己有解析记录的缓存,由于我们在proxy_pass中使用的是域名,这种场景在实际上是存在的,面对这种场景你有2个办法:
reload nginx,这种办法对于域名解析变动非常不频繁的情况
使用变量,这种办法对于域名解析比较频繁的情况
如何使用变量呢,如下所示:
server { listen 80; server_name ; # 新增 resolver 127.0.0.1:5353 [::1]:5353 valid=30s; access_log /var/log/nginx/www.test.com/access.log detailed; error_log /var/log/nginx/www.test.com/error.log error; location / { # 新增 set $backendname ; # proxy_pass :5555; proxy_pass $backendname:5555; proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; } ...... }先说一下变量名引用和直接代理有什么不同:
proxy_pass :5555 这种方式将tengine在启动的时候使用系统的域名服务器把解析成ip。 如果系统的域名服务器不能解析出ip,tengine将不能启动。
变量方式,tengine在运行的时候动态解析域名,也就是在访问的时候才进行解析,使用Tengine的 reslover 指令配置的域名服务器。 tengine会保存域名解析的TTL时间,在TTL时间内直接使用这个ip,过期之后重新域名解析。
两者的利弊: 第一种不会感知到域名的ip变动,启动之后就不依赖域名服务器; 第二种配置会感知到域名的ip变动,但运行时依赖域名服务器,如果域名服务器挂了会返回502,而并不会尝试使用本机配置的其他DNS服务器来解析。
注意:通过变量的形式配置如果你不resolver的话,Nginx是不会用本地的hosts或者resolv文件去解析的。
我这里就在我Nginx这个服务器上安装了一个dnsmasq,通过yum安装yum -y install dnsmasq,编辑配置文件/etc/dnsmasq.conf:
port=5353 listen-address=127.0.0.1 resolv-file=http://www.likecs.com/etc/resolv.conf addn-hosts=http://www.likecs.com/etc/hosts最关键的就是最后一句,因为对的解析就在本地hosts文件中。配置好后启动服务。然后再次访问页面就可以了。
小结针对504的我们模拟了2种情况,你从error日志里看其实根本原因都一样就是连接超时,只不多第一种是属于主动超时,第二种属于被动超时,但不管怎么样都是在一定时间内得不到响应,这种响应可以是连接层面的响应也可以是后端数据返回的响应,但重点不在响应本身而是在于一定时间。
总结499无需多说,这个在Nginx代码的定义就是NGX_HTTP_CLIENT_CLOSED_REQUEST,客户端关闭请求,这就是Nginx产生499的原因,这句定义你可以解读出2个信息,第一客户端和Nginx已经建立了连接,第二在Nginx还没有完成响应动作的时候客户端关闭了连接,至于客户端为什么关闭请求那是另外一回事。