假设nginx设置如下:
location / {
proxy_read_timeout 10; # https://github.com/gitlabhq/gitlabhq/issues/694 proxy_connect_timeout 30; # https://github.com/gitlabhq/gitlabhq/issues/694 proxy_redirect off; proxy_next_upstream error timeout;
读超时10秒,timeout时重试, nginx访问的是B程序。 --------------------------------------------------- A程序调用nginx,A程序的超时是30秒,那么 A->nginx->B
例子1: (1)第一次,B在10秒内没输出 (2)nginx认为超时,自动重试,第二次依然10秒超时,返回504 Gateway Time-out (我的nginx只代理了一个tomcat,多个tomcat是否会重试多次,这个没有试!) (3)A程序获得的内容是504 Gateway Time-out页面。
例子2: (1)第一次,B在10秒内没输出 (2)nginx认为超时,自动重试,第二次B程序10秒内返回内容 (3)A程序获得的内容是B程序第二次返回的内容。 --------------------------------------------------- 问题就是,有些请求是不应该重试的,比如出票,可能导致重复出票。 如一个出票请求可能要200秒返回成功,第一次超时时,实际正在处理。 但nginx自动发起第二次请求,可能会重复出票。 ---------------------------------------------
解决方法: proxy_next_upstream配置参数里的timeout去掉,即超时不重试。 刷新一下nginx配置
注意,默认值是proxy_next_upstream error timeout 即,你不写proxy_next_upstream 这个参数,会超时重试,哈哈。 ===================================================== proxy_next_upstream
语法: proxy_next_upstream [error|timeout|invalid_header|http_500|http_503|http_404|off]
默认值: proxy_next_upstream error timeout
上下文: http, server, location
Directive determines, in what cases the request will be transmitted to the next server:
·error ― an error has occurred while connecting to the server, sending a request to it, or reading its response; ·timeout ― occurred timeout during the connection with the server, transfer the requst or while reading response from the server; ·invalid_header ― server returned a empty or incorrect answer; ·http_500 ― server returned answer with code 500 ·http_503 ― server returned answer with code 503 ·http_404 ― server returned answer with code 404 ·off ― it forbids the request transfer to the next server
Transferring the request to the next server is only possible when nothing has been transferred to the client -- that is, if an error or timeout arises in the middle of the transfer of the request, then it is not possible to retry the current request on a different server.
如果有内容发送给client了,则不会重试。
|