如何阻止 nginx 在上游服务器超时时重试 PUT 或 POST 请求?

如何阻止 nginx 在上游服务器超时时重试 PUT 或 POST 请求?

我们正在使用 nginx 来平衡应用程序的请求负载。我们发现,当请求超时时,nginx 会切换到不同的上游服务器(很好)。但是,它对 PUT 和 POST 请求执行此操作,这可能会导致不良结果(数据存储两次)。是否可以将 nginx 配置为仅在超时时重试 GET 请求?或者还有其他方法可以解决问题?

我们的配置如下:

upstream mash {
    ip_hash;
    server 127.0.0.1:8081;
    server 192.168.0.11:8081;
}

server {
    ...
    location / {
        proxy_pass http://mash/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;        
    }
}

答案1

从 nginx 开始1.9.13,默认情况下不会重试非幂等请求(PUTPOST等)。如果您可以升级到此版本或更高版本,则可以默认获得所需的行为。

如果由于某种原因您想要在 1.9.13 或更高版本上继续重试PUTPOST等(非幂等)请求,请使用:

proxy_next_upstream error timeout non_idempotent;

答案2

我知道我参与这个游戏已经很晚了,但是对我来说,这是搜索此问题时的最佳结果,所以我想分享我的解决方案。

这使用if 指令(与少数有效用例)与自定义错误处理程序

upstream backend {
    server backend1;
    server backend2;
}

server {
    server_name proxy;

    location / {
        error_page 598 = @retry;
        error_page 599 = @no_retry;
        if ($request_method = POST) {
            return 599;
        }
        return 598;
    }

    location @retry {
        proxy_pass http://backend;
    }

    location @no_retry {
        proxy_pass http://backend;
        proxy_next_upstream off;
    }
}

答案3

请参阅此处的文档:proxy_next_upstream

请注意,这是一个未经测试的要点

https://gist.github.com/wojons/6154645

答案4

我的 tomcat 服务器也遇到了同样的问题。当出现长请求时,代理会超时。我通过使用 proxy_read_timeout 解决了这个问题。当增加超时时间时,我的请求永远不会超时,也不会出现任何问题。默认超时时间为 60 秒。参考

location / {
    proxy_pass  http://xxxxxxxxxx.com;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_set_header X-Forwarded-Proto https;
            proxy_redirect off;
            proxy_connect_timeout      800;
            proxy_send_timeout         800;
            proxy_read_timeout         240;     
}

相关内容