Nginx部分配置如下:
//upstream配置
upstream my.upstream.com {
server 10.1.1.2 max_fails=1 fail_timeout=10s;
server 10.1.1.
3
max_fails=1 fail_timeout=10s;
#max_fails默认值为1,
fail_timeout
默认值为10s,max_fails=0表示不做检查
}
//location配置
location ~ / {
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 60s; #默认值60s, nginx连接到后端服务器的连接超时时间
proxy_timeout 10m; #默认值为10分钟,nginx接收后端服务器的响应超时时间
proxy_pass http://my.upstream.com;
}
max_fails和
fail_timeout
参数是配合使用的,按默认值,当某台upstream server挂了,表示在10s(
fail_timeout
)之内,有1(max_fails)个请求打到这台挂了的服务器,nginx就会把这台upstream server设为down机的状态,时长是10s,在这10s内如果又有请求进来,就不会被转到这台server上,过了10s重新认为这台server又恢复了
背景介绍:由于API集群中的一台服务器(比如:10.1.1.2 服务器D)挂了,导致nginx转到服务器D的请求全部超时,感觉没有降级的策略,最后对Nginx的配置做了一个熟悉,最后发现是我们的配置没有优化的原因;
现象:当客户端的请求打到Nginx,Nginx把请求转到服务器D,由于nginx的proxy_connect_timeout 超时时间为60s,就会导致Nginx把客户端的请求转到服务器D的时候,就会尝试连接60s,而客户端的响应时间设的是3s,所以造成客户端造成大量超时情况,Nginx报大量的499;
讨论:给Nginx造成很大的资源负担,既然后端服务器D已经挂了,每次转到服务器D的请求重连60s确实太久,所以这次参数需要优化,如果是提供服务方,这个时间要小于服务适用方可接受的响应超时时间,我们服务后来设置的是2s(小于客户端响应超时时间3s),max_fails使用默认值1,
fail_timeout
也设置的是30s,表示30s内如果发现一次连接到某台upstream server超过2s,则这台server在30s不会有请求过来,这样能保证某台server down机后,在3s秒内下一台upstream能将请求结果返回给客户端(因为我们后端服务器的处理时间是小于几十ms的,所以可以保证3s内能将结果返回),也能保证后面的请求在30s不会打到这台server,还能保证如果服务恢复了,最多让服务器空转30s,后续会继续服务。
PS:个人觉得proxy_timeout 没有设置的必要,使用默认值,如果proxy_timeout 设置过小nginx会直接返回给客户端错误,不是一次成功的请求,设置过大,客户端直接报响应超时,所以建议使用默认值,如果真的响应慢了,只能去优化代码的逻辑了。