首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

nginx自动重试导致的post提交两次

nginx自动重试导致的post提交两次

遇到问题---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配置。


方法二
给长时间的方法加上静态变量判断,做一个开关锁,保证只有一次运行
返回列表