Erreur Bad Gateway 502 avec Apache mod proxy et Tomcat
Nous exécutons une application web sur Tomcat 6 et Apache mod_proxy 2.2.3. Voir beaucoup d'erreurs 502 comme ceci:
Mauvaise Passerelle! Le serveur proxy a reçu une réponse non valide d'un serveur en amont.
Le serveur proxy n'a pas pu gérer la requête GET / the / page. do.
Raison: erreur de lecture depuis le serveur distant
Si vous pensez qu'il s'agit d'une erreur de serveur, veuillez contacter le webmaster.
Erreur 502
Tomcat a beaucoup de threads, donc ce n'est pas contraint par les threads. Nous poussons les utilisateurs 2400 via JMeter contre l'application. Toutes les boîtes sont assis à l'intérieur de notre pare-feu sur un réseau déchargé rapide, donc il ne devrait pas y avoir de problèmes de réseau.
Quelqu'un a des suggestions de choses à regarder ou essayer? Nous nous dirigeons vers tcpdump suivant.
Mise à jour 10/21/08: Je N'ai toujours pas compris cela. Voir seulement un très petit nombre de ceux-ci sous charge. Les réponses ci-dessous n'ont fourni aucune réponse magique...encore. :)
8 réponses
Juste pour ajouter quelques paramètres spécifiques, j'ai eu une configuration similaire (avec Apache 2.0.63 reverse proxying sur Tomcat 5.0.27).
Pour certaines URL, le serveur Tomcat peut prendre 20 minutes pour retourner une page.
J'ai fini par Modifier les paramètres suivants dans le fichier de configuration Apache pour l'empêcher de temporiser avec son opération proxy (avec un grand facteur de débordement au cas où Tomcat prendrait plus de temps pour retourner une page):
Timeout 5400
ProxyTimeout 5400
Certains backgound
ProxyTimeout seul ne suffisait pas. En regardant la documentation de Timeout je suis devinant (Je ne suis pas sûr) que C'est parce que pendant Qu'Apache attend une réponse de Tomcat, il n'y a pas de trafic entre Apache et le navigateur (ou quel que soit le client http) - et donc Apache ferme la connexion au navigateur.
J'ai trouvé que si je laissais le paramètre Timeout à sa valeur par défaut (300 secondes), alors si la requête proxyed à Tomcat il a fallu plus de 300 secondes pour obtenir une réponse, le navigateur afficherait une page "erreur de Proxy 502". Je crois que ce message est généré par Apache, sachant qu'il agit comme un proxy inverse, avant de fermer la connexion au navigateur (c'est ma compréhension actuelle - il peut être défectueux).
La page d'erreur du proxy indique:
Erreur De Proxy
Le serveur proxy a reçu un réponse à partir d'un serveur en amont. Le le serveur proxy n'a pas pu la poignée de la demande OBTENIR.
Raison: erreur de lecture depuis le serveur distant
...ce qui suggère que C'est le paramètre ProxyTimeout qui est trop court, tandis que l'enquête montre que le paramètre Timeout D'Apache (délai entre Apache et le client) influence également cela.
Donc, répondre à ma propre question ici. Nous avons finalement déterminé que nous voyions des erreurs 502 et 503 dans l'équilibreur de charge en raison de la temporisation des threads Tomcat. À court terme, nous avons augmenté le délai d'attente. À plus long terme, nous avons corrigé les problèmes d'application qui causaient les délais d'attente en premier lieu. Pourquoi les délais D'attente Tomcat étaient perçus comme des erreurs 502 et 503 à l'équilibreur de charge est encore un peu un mystère.
Vous pouvez utiliser proxy-premiers-pas-commun
Voir http://httpd.apache.org/docs/2.2/mod/mod_proxy_http.html :
Si cette variable est définie, aucune connexion groupée ne sera réutilisée si la connexion client est une connexion initiale. Cela évite le message d'erreur" proxy: error reading status line from remote server " causé par la condition de concurrence selon laquelle le serveur principal a fermé la connexion groupée après la vérification de la connexion par le proxy et avant que les données envoyées par le serveur le proxy a atteint le backend. Il faut garder à l'esprit que la définition de cette variable rétrograde les performances, en particulier avec les clients HTTP/1.0.
Nous avons eu ce problème aussi. Nous l'avons corrigé en ajoutant
SetEnv proxy-nokeepalive 1
SetEnv proxy-initial-not-pooled 1
Et désactiver keepAlive
sur tous les serveurs.
Mod_proxy_http est bien dans la plupart des scénarios mais nous l'exécutons avec une charge lourde et nous avons encore des problèmes de délai d'attente que nous ne comprenons pas.
Mais voyez si la directive ci-dessus correspond à vos besoins.
Exemple de configuration apache:
# la valeur par défaut est de 2 minutes.
Délai d'attente 600
La directive proxyrequests off
ProxyPass / app balancer: / / MyApp stickysession=JSESSIONID lbmethod=bytraffic nofailover=On
ProxyPassReverse / app balancer: / / MyApp
ProxyTimeout 600
BalancerMember http://node1:8080/ route=node1 retry=1 max=25 délai d'expiration=600
.........
Je devine que vous utilisez mod_proxy_http (ou équilibreur de proxy).
Regardez dans vos journaux tomcat (localhost.journal, ou catalina.log) je soupçonne que vous voyez une exception dans votre pile web bouillonnant et fermant le socket auquel le travailleur tomcat est connecté.
Vous devriez pouvoir résoudre ce problème via un paramètre timeout et proxyTimeout défini sur 600 secondes. Cela a fonctionné pour moi après avoir lutté pendant un certain temps.
Vous pouvez éviter les délais d'attente globaux ou les hôtes virtuels en spécifiant les délais d'attente proxy dans la directive ProxyPass comme suit:
ProxyPass /svc http://example.com/svc timeout=600
ProxyPassReverse /svc http://example.com/svc timeout=600
Notez timeout=600
secondes.
Cependant, cela ne fonctionne pas toujours lorsque vous avez un équilibreur de charge. Dans ce cas, vous devez ajouter les délais d'attente aux deux endroits (testés dans Apache 2.2.31)
Exemple D'équilibreur de charge:
<Proxy "balancer://mycluster">
BalancerMember "http://member1:8080/svc" timeout=600
BalancerMember "http://member2:8080/svc" timeout=600
</Proxy>
ProxyPass /svc "balancer://mycluster" timeout=600
ProxyPassReverse /svc "balancer://mycluster" timeout=600
Une note de côté: le timeout=600
sur ProxyPass
n'était pas nécessaire lorsque Chrome était le client (Je ne sais pas pourquoi) mais sans cela le délai d'attente sur ProxyPass
Internet Explorer (11) annule la réinitialisation de la connexion par le serveur.
Ma théorie est que le:
ProxyPass
le délai d'attente est utilisé entre le client (navigateur) et Apache.
BalancerMember
le délai d'attente est utilisé entre Apache et le backend.
Pour ceux qui utilisent Tomcat ou d'autres sauvegardes, vous pouvez également faire attention aux délais D'attente du connecteur HTTP.
Très probablement, vous devriez augmenter le paramètre Timeout dans apache conf (valeur par défaut 120 sec)