Nginx [测试环境 Tengine version: Tengine/2.2.0 (nginx/1.8.1)] 作为负载均衡时,若后端某个服务器超时,Nginx 会将请求重新发送到另一个服务器,如果是读操作会没问题,若请求是写操作,则可能会发生重复提交问题。即某个请求在 a 服务器上提交了一次,在 b 服务器上又提交了一次。

解决方法很简单,将 proxy_next_upstrea 设置为 off 或按照下面文档设置即可。

Syntax: proxy_next_upstream error | timeout | invalid_header | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | http_429 | non_idempotent | off ...;
Default: proxy_next_upstream error timeout;
Context: http, server, location

Specifies in which cases a request should be passed to the next server:

  • error an error occurred while establishing a connection with the server, passing a request to it, or reading the response header;
  • timeout a timeout has occurred while establishing a connection with the server, passing a request to it, or reading the response header;
  • invalid_header a server returned an empty or invalid response;
  • http_500 a server returned a response with the code 500;
  • http_502 a server returned a response with the code 502;
  • http_503 a server returned a response with the code 503;
  • http_504 a server returned a response with the code 504;
  • http_403 a server returned a response with the code 403;
  • http_404 a server returned a response with the code 404;
  • http_429 a server returned a response with the code 429 (1.11.13);
  • non_idempotent normally, requests with a non-idempotent method (POST, LOCK, PATCH) are not passed to the next server if a request has been sent to an upstream server (1.9.13); enabling this option explicitly allows retrying such requests;
  • off disables passing a request to the next server.

One should bear in mind that passing a request to the next server is only possible if nothing has been sent to a client yet. That is, if an error or timeout occurs in the middle of the transferring of a response, fixing this is impossible.

The directive also defines what is considered an unsuccessful attempt of communication with a server. The cases of error, timeout and invalid_header are always considered unsuccessful attempts, even if they are not specified in the directive. The cases of http_500, http_502, http_503, http_504, and http_429 are considered unsuccessful attempts only if they are specified in the directive. The cases of http_403 and http_404 are never considered unsuccessful attempts.

Passing a request to the next server can be limited by the number of tries and by time.

还有一个重复次数设置。

Syntax: proxy_next_upstream_tries number;
Default: proxy_next_upstream_tries 0;
Context: http, server, location