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

Dav*_*ker 12 nginx reverse-proxy

我们正在使用 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;        
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 10

1.9.13版开始,它已成为默认行为

要手动将其改回,您可以使用:

proxy_next_upstream error timeout non_idempotent;
Run Code Online (Sandbox Code Playgroud)

  • 这个答案有点误导。OP 不想将 PUT 和 POST 请求发送到下一个上游服务器。从1.9.13版本开始,非幂等请求(PUT、POST、LOCK)不再默认发送到下一个上游服务器。仅当您想在错误或超时时向下一个上游服务器发送 PUT、POST、LOCK 请求时,才使用“proxy_next_upstream error timeout non_idempot;”。 (2认同)

小智 6

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

这使用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;
    }
}
Run Code Online (Sandbox Code Playgroud)


Woj*_*ech 4

请参阅此处的文档:proxy_next_upstream

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

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