2 votes

Capture des erreurs de type upstream down (502) et affichage d'une page d'erreur personnalisée

Cette question aurait dû trouver une réponse il y a longtemps, mais je ne parviens pas à la résoudre malgré la lecture de nombreuses réponses communes. Quelqu'un peut-il m'indiquer pourquoi ma configuration ne fonctionne pas ?

Objectif : lorsque l'API serveur en amont est hors service (par exemple, ses processus de travail se sont écrasés), je veux que nginx affiche ma page d'erreur personnalisée.

Ma configuration :

location @server {
    proxy_pass http://server_api;
    proxy_redirect off;
    ...

    proxy_intercept_errors on;
    error_page 502 /error-502.html;
}

error_page 502 /error-502.html;

location = /error-502.html {
    internal;
    root /srv/my-server/html;
}

Mes pas :

  • Ma page d'erreur statique est à /srv/my-server/html/error-502.html prêt, même permission et mêmes propriétaires que les autres actifs statiques.
  • J'ai arrêté mon service en amont, et je vois [error] 2359#0: *25 connect() failed (111: Connection refused) while connecting to upstream apparaissant dans les journaux.
  • J'essaie maintenant de faire en sorte que ma page d'erreur personnalisée s'affiche pour les erreurs 502.
  • J'ai essayé de régler error_page à l'un ou l'autre ou aux deux server o location bloc.
  • J'ai essayé error_page con proxy_intercept_errors on dans le location o server bloc ;

Aucun d'entre eux ne semble persuader nginx d'afficher ma page d'erreur. Pourquoi pas ? Qu'est-ce que j'ai raté ?

6voto

Josh Ross Points 156

Merci Justin et Michael de m'avoir orienté dans la bonne direction, c'est en effet un bloc de localisation qui cause mes problèmes, en particulier :

location / {
    try_files   $uri $uri/ @server;
    error_page  403 = @server;
}

En gros, j'essayais d'être malin et d'attraper $uri/ (403 se produit lorsque vous essayez d'accéder à un dossier qui existe mais qui n'a pas de fichier d'index ou d'auto-indexation) et redirigez-le vers @server également.

Mais n'est-ce pas try_files $uri $uri/ @server; seul, c'est suffisant ?

Imaginez que vous essayez d'accéder http://example.com/ nginx dira, oh ce dossier existe (c'est votre root ) mais aucun index n'a été trouvé, et nous jetons 403 au lieu de passer sur @server bloc.

C'est ainsi que j'ai trouvé la solution 403, mais je n'ai pas réalisé qu'elle avait un coût : cela signifie que nginx a déjà détecté une erreur et utilisé error_page dans le même location pour le traiter (en le passant à @server ).

Si l'on ajoute à cela les tests que j'ai effectués dans la question, il semble que nginx (v1.7.x) ne tienne pas compte de la suite des événements. error_page à ce stade et utiliser la directive 502 par défaut à la place.

La partie intéressante : comment contourner ce problème ?

Ma solution est de mettre en place une route correspondant exactement à la racine à la place, maintenant il n'est plus nécessaire d'attraper 403 sur la racine, et error_page fonctionne comme prévu.

error_page 502 /error-502.html;

location = /error-502.html {
    internal;
    root /srv/example.com/html;
}

location = / {
    try_files $uri @server;
}

location / {
    try_files $uri $uri/ @server;
}

1voto

Il est difficile d'en être sûr sans voir l'ensemble de votre configuration, car cela fonctionne pour moi sans aucune des mesures supplémentaires que vous avez prises. J'ai d'abord essayé toute votre configuration, puis j'ai enlevé des éléments un par un pour voir si quelque chose changeait.

Il ne devrait pas être nécessaire d'utiliser proxy_intercept_errors, car le 502 est généré par nginx lui-même lorsqu'il ne parvient pas à se connecter au backend. J'ai confirmé que cela a fonctionné pour moi avec cette configuration et cette désactivation.

Tout ce que j'ai ajouté, à l'intérieur de mon bloc serveur est :

error_page 502 /error-502.html;

location = /error-502.html {
  internal;
  root /srv/www/errors;
}

Dans ma configuration, mes pages d'erreurs statiques sont dans /srv/www/errors, mais rien d'autre n'est différent.

Vous devez avoir une configuration ailleurs qui est à l'échelle du serveur ou dans votre bloc de serveur qui interfère ou remplace. Faites attention aux règles de préséance pour les emplacements, cela pourrait être un facteur.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X