Nginx参数proxy_next_upstream和fastcgi_next_upstream的用法注意事项
2016-10-20Linux撒加9057°c
A+ A-大部分时候Nginx都被应用在反代+负载均衡的场景中,在此种场景下避免不了要使用到ngx_http_fastcgi_module、ngx_http_proxy_module以及ngx_http_upstream_module。
ngx_http_upstream_module用于定义服务器组给ngx_http_fastcgi_module和ngx_http_proxy_module使用,同时提供一些负载均衡算法来处理用户请求。在定义服务器组的时候,通常server的数量是大于1的,此时proxy_next_upstream和fastcgi_next_upstream参数就会被广大的SA应用,因为这两个参数的指定了在发生一些情况的时候可以将请求发送到upstream中的下一台服务器,多么好的功能啊,似乎用了这个参数就可以避免给用户端返回错误了。恩。。。确实是的,当upstream中的一台server出现状况时,请求被转发到了其他服务器上,access_log中也可以看到了(前提是你的log format配置的合适),通常一个请求只会被一个server处理,如果你看到请求被两个server处理,就是请求retry了。
这样跑一段时间,如果某天你发现某些数据被提交了2次时,哈哈,恭喜你,你掉入了这两个参数的坑。先来看这两个参数在哪些情况发生的时候会retry。
对于ngx_http_proxy_module来说有以下情况:
error
:和后端服务器建立连接时,或者向后端服务器发送请求时,或者从后端服务器接收响应头时,出现错误;
timeout
:和后端服务器建立连接时,或者向后端服务器发送请求时,或者从后端服务器接收响应头时,出现超时;
invalid_header
:后端服务器返回空响应或者非法响应头;
http_500
:后端服务器返回的响应状态码为500;
http_502
:后端服务器返回的响应状态码为502;
http_503
:后端服务器返回的响应状态码为503;
http_504
:后端服务器返回的响应状态码为504;
http_404
:后端服务器返回的响应状态码为404;
http_403:后端服务器返回的响应状态吗为403。
对于ngx_http_fastcgi_module来说有以下情况:
error
:和后端服务器建立连接时,或者向后端服务器发送请求时,或者从后端服务器接收响应头时,出现错误;
timeout
:和后端服务器建立连接时,或者向后端服务器发送请求时,或者从后端服务器接收响应头时,出现超时;
invalid_header
:后端服务器返回空响应或者非法响应头;
http_500
:后端服务器返回的响应状态码为500;
http_503
:后端服务器返回的响应状态码为503;
http_404
:后端服务器返回的响应状态码为404;
http_403:后端服务器返回的响应状态吗为403。
一般对于HTTP GET请求,next_upstream不会出问题,但如果是POST请求就会发生重复提交的问题。为了避免这种问题,是需要做配置的
对于1.9.13之前的版本,可以用如下的方法来避免next_upstream
upstream backend {
server backend1;
server backend2;
}
server {
server_name xxxxx;
location / {
error_page 600 = @retry;
error_page 601 = @no_retry;
if ($request_method = POST) {
return 601;
}
return 600;
}
location @retry {
proxy_pass https://backend;
}
location @no_retry {
proxy_pass https://backend;
proxy_next_upstream off;
}
}
对于1.9.13以上版本,proxy_next_upstream和fastcgi_next_upstream默认就不会对non idempotent的方法做next upstream操作,除非显式指定non_idempotent。
PS:
1、两个指令的默认都是发生error和timeout时,会将请求发送到下一台服务器
2、只有在没有向客户端发送任何数据以前,将请求转给下一台后端服务器才是可行的。也就是说,如果在传输响应到客户端时出现错误或者超时,这类错误是不可能恢复的。