遇到问题---web访问超长时间操作请求时方法会自动运行两次。
原因
nginx自动重试导致的post提交两次。
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.
举例
假设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配置。
方法二
给长时间的方法加上静态变量判断,做一个开关锁,保证只有一次运行 |