Comment puis-je empêcher nginx de réessayer les requêtes PUT ou POST sur le délai d'expiration du serveur en amont?

11

Nous utilisons nginx pour charger les demandes d'équilibrage dans notre application. Nous avons constaté que nginx bascule vers un autre serveur en amont lorsque les demandes expirent (bon). Cependant, il le fait pour les requêtes PUT et POST qui peuvent entraîner des résultats indésirables (données stockées deux fois). Est-il possible de configurer nginx pour n'essayer à nouveau que les requêtes GET sur timeout? Ou existe-t-il une autre façon de résoudre le problème?

Notre configuration est la suivante:

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
la source

Réponses:

9

C'est devenu un comportement par défaut à partir de la version 1.9.13

Pour le modifier manuellement, vous pouvez utiliser:

proxy_next_upstream error timeout non_idempotent;
Pavel Evstigneev
la source
6

Je sais que je suis assez tard dans le jeu, mais pour moi, c'est le meilleur résultat lors de la recherche de ce problème, donc je voulais partager ma solution.

Cela utilise la directive if (avec l'un des rares cas d'utilisation valides ) combinée avec le gestionnaire d'erreurs personnalisé :

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
la source
4

Veuillez voir ici pour le doc: proxy_next_upstream

Veuillez noter qu'il s'agit d'un élément non testé

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

WojonsTech
la source
En fait, cela n'a pas fonctionné: Nginx dit que "proxy_next_upstream n'est pas autorisé ici". J'ai essayé de déplacer les blocs if dans leur emplacement et j'ai eu la même erreur. Utilisation de "proxy_next_upstream error" dans l'un ou l'autre emplacement sur ses propres œuvres.
David Tinker
c'est très étrange car la documentation indique clairement que cela fonctionne dans le contexte de l'emplacement
WojonsTech
il semble que ce soit le (...) {} autour de proxy_next_upstream que nginx n'aime pas
David Tinker
Quelqu'un a-t-il testé cela? 4 votes positifs mais il ne semble pas adhérer à des cas d'utilisation valides ici: nginx.com/resources/wiki/start/topics/depth/ifisevil
EoghanM
0

proxy_methoddirective d' utilisation

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

yuankui
la source
2
Il est généralement recommandé d'inclure les informations utiles d'un lien dans votre réponse afin qu'il ne repose pas explicitement sur le lien pour être utile
BE77Y
1
Bienvenue dans Server Fault! Bien que cela puisse théoriquement répondre à la question, il serait préférable d'inclure ici les parties essentielles de la réponse et de fournir le lien de référence.
Mark Henderson
-1

J'ai le même problème sur mon serveur tomcat. délai d'expiration du proxy lorsque la demande est longue. j'ai résolu mon problème en utilisant proxy_read_timeout. lorsque l'augmentation du délai d'attente alors ma demande n'a jamais expiré et aucun problème ne s'est produit. délai d'expiration par défaut des années 60. référence

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
la source
1
Cela ne répond pas du tout à la question. Vos problèmes ne se ressemblent pas.
Sven