¿Cómo puedo evitar que nginx vuelva a intentar las solicitudes PUT o POST en el tiempo de espera del servidor ascendente?

11

Estamos utilizando nginx para cargar solicitudes de saldo en nuestra aplicación. Hemos encontrado que nginx cambia a un servidor ascendente diferente cuando se agota el tiempo de espera de las solicitudes (bueno). Sin embargo, hace esto para solicitudes PUT y POST que pueden causar resultados no deseados (datos almacenados dos veces). ¿Es posible configurar nginx para volver a intentar solo las solicitudes GET en el tiempo de espera? ¿O hay otra forma de resolver el problema?

Nuestra configuración es la siguiente:

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;        
    }
}
David Tinker
fuente

Respuestas:

9

Se convirtió en un comportamiento predeterminado a partir de la versión 1.9.13

Para volver a cambiarlo manualmente, puede usar:

proxy_next_upstream error timeout non_idempotent;
Pavel Evstigneev
fuente
6

Sé que llego bastante tarde al juego, pero para mí este es el mejor resultado cuando busco este problema, así que quería compartir mi solución.

Utiliza la directiva if (con uno de los pocos casos de uso válidos ) combinada con el controlador de errores personalizado :

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;
    }
}
ddelbondio
fuente
4

Consulte aquí para ver el documento: proxy_next_upstream

Tenga en cuenta que esta es una esencia no probada

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

WojonsTech
fuente
En realidad no funcionó: Nginx dice "proxy_next_upstream no permitido aquí". Intenté mover los bloques if a su ubicación y obtuve el mismo error. Usar "proxy_next_upstream error" en cualquier ubicación en sus propios trabajos.
David Tinker
eso es muy extraño ya que la documentación dice claramente que funciona en el contexto de la ubicación
WojonsTech
parece ser el if (...) {} alrededor de proxy_next_upstream que a nginx no le gusta
David Tinker
¿Alguien ha probado esto? 4 votos a favor, pero no parece cumplir con los casos de uso válidos aquí: nginx.com/resources/wiki/start/topics/depth/ifisevil
EoghanM
0

proxy_methoddirectiva de uso

consulte: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_method

yuankui
fuente
2
En general, se recomienda incluir la información útil de un enlace en su respuesta de modo que no dependa explícitamente de que el enlace sea útil
BE77Y
1
¡Bienvenido a Server Fault! Si bien esto puede responder teóricamente la pregunta, sería preferible incluir aquí las partes esenciales de la respuesta y proporcionar el enlace para referencia.
Mark Henderson
-1

Tengo el mismo problema en mi servidor Tomcat. tiempo de espera del proxy cuando se produce una solicitud larga. Resolví mi problema usando proxy_read_timeout. cuando aumenta el tiempo de espera, entonces mi solicitud nunca expiró y no se produjo ningún problema. tiempo de espera predeterminado 60 s. referencia

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;     
}
hmtmcse
fuente
1
Esto no responde a la pregunta en absoluto. Tus problemas no son iguales.
Sven