it-swarm.com.de

Fehlerhafter Gateway 502-Fehler mit Apache mod_proxy und Tomcat

Wir führen eine Web-App auf Tomcat 6 und Apache mod_proxy 2.2.3 aus. Viele 502 Fehler sehen so aus:

Schlechtes Gateway! Der Proxy-Server hat eine ungültige Antwort von einem Upstream-Server erhalten.

Der Proxy-Server konnte die Anforderung GET /the/page.do nicht verarbeiten.

Grund: Fehler beim Lesen vom Remote-Server

Wenn Sie glauben, dass dies ein Serverfehler ist, wenden Sie sich an den Webmaster.

Fehler 502

Tomcat hat viele Threads und ist daher nicht auf Threads beschränkt. Wir haben 2400 Benutzer über JMeter gegen die App gedrängt. Alle Boxen befinden sich in unserer Firewall in einem schnell entladenen Netzwerk, sodass es keine Netzwerkprobleme geben sollte.

Hat jemand Vorschläge für Dinge zum Anschauen oder Ausprobieren? Wir fahren als nächstes zum tcpdump.

UPDATE 21.10.08: Ich habe es immer noch nicht herausgefunden. Sehen Sie nur eine sehr kleine Anzahl davon unter Last. Die folgenden Antworten haben noch keine magischen Antworten geliefert. :)

46
Alex Miller

Hier beantworte ich meine eigene Frage. Letztendlich stellten wir fest, dass 502 und 503 Fehler im Load Balancer aufgetreten sind, weil das Timing von Tomcat-Threads abgelaufen ist. Kurzfristig haben wir das Timeout erhöht. Langfristig haben wir die App-Probleme behoben, die zu Timeouts geführt haben. Warum Tomcat-Timeouts beim Load Balancer als 502- und 503-Fehler wahrgenommen wurden, ist immer noch ein Rätsel.

13
Alex Miller

Um einige spezifische Einstellungen hinzuzufügen, hatte ich ein ähnliches Setup (mit Apache 2.0.63 Reverse Proxying auf Tomcat 5.0.27).

Bei bestimmten URLs kann der Tomcat-Server möglicherweise 20 Minuten benötigen, um eine Seite zurückzugeben.

Ich habe die folgenden Einstellungen in der Apache-Konfigurationsdatei geändert, um zu verhindern, dass das Zeitlimit für den Proxy-Vorgang überschritten wird (mit einem großen Überlauffaktor für den Fall, dass Tomcat länger benötigt, um eine Seite zurückzugeben):

Timeout 5400
ProxyTimeout 5400

Ein bisschen backgound

ProxyTimeout allein hat nicht gereicht. In der Dokumentation nach Timeout Ich vermute (ich bin nicht sicher), dass dies daran liegt, dass Apache wartet Für eine Antwort von Tomcat fließt kein Datenverkehr zwischen Apache und dem Browser (oder einem beliebigen http-Client). Apache beendet daher die Verbindung zum Browser.

Ich stellte fest, dass, wenn ich die Standardeinstellung für das Zeitlimit (300 Sekunden) beließ und die Proxy-Anforderung an Tomcat länger als 300 Sekunden dauerte, um eine Antwort zu erhalten, vom Browser die Seite "502 Proxy Error" angezeigt wurde. Ich glaube, diese Nachricht wird von Apache in dem Wissen generiert, dass sie als Reverse-Proxy fungiert, bevor die Verbindung zum Browser getrennt wird (dies ist nach meinem derzeitigen Verständnis fehlerhaft).

Die Proxy-Fehlerseite lautet:

Proxy-Fehler

Der Proxy-Server hat eine ungültige Antwort von einem Upstream-Server erhalten. Der Proxy-Server konnte die Anforderung GET nicht verarbeiten.

Grund: Fehler beim Lesen vom Remote-Server

... was darauf hindeutet, dass die ProxyTimeout-Einstellung zu kurz ist, während die Untersuchung zeigt, dass die Timeout-Einstellung von Apache (Timeout zwischen Apache und dem Client) dies ebenfalls beeinflusst.

42
Neil Salter

Sie können proxy-initial-not-pooled verwenden

Siehe http://httpd.Apache.org/docs/2.2/mod/mod_proxy_http.html :

Wenn diese Variable gesetzt ist, wird keine Pool-Verbindung wiederverwendet, wenn es sich bei der Client-Verbindung um eine Erstverbindung handelt. Dadurch wird die Fehlermeldung "Proxy: Fehler beim Lesen der Statuszeile vom Remoteserver" vermieden, die durch die Race-Bedingung verursacht wird, dass der Back-End-Server die Pool-Verbindung geschlossen hat, nachdem der Proxy die Verbindung überprüft hat und bevor die vom Proxy gesendeten Daten das Back-End erreicht haben. Es ist zu beachten, dass durch das Festlegen dieser Variablen die Leistung herabgesetzt wird, insbesondere bei HTTP/1.0-Clients.

Wir hatten auch dieses Problem. Wir haben es durch Hinzufügen behoben

SetEnv proxy-nokeepalive 1
SetEnv proxy-initial-not-pooled 1

und keepAlive auf allen Servern ausschalten.

mod_proxy_http ist in den meisten Szenarien in Ordnung, aber wir führen es mit hoher Last aus und wir haben immer noch einige Timeout-Probleme, die wir nicht verstehen.

Prüfen Sie jedoch, ob die obige Richtlinie Ihren Anforderungen entspricht.

9
Janning

Beispiel aus Apache conf:

#Default value is 2 minutes
**Timeout 600**
ProxyRequests off
ProxyPass /app balancer://MyApp stickysession=JSESSIONID lbmethod=bytraffic nofailover=On
ProxyPassReverse /app balancer://MyApp
ProxyTimeout 600
<Proxy balancer://MyApp>
    BalancerMember http://node1:8080/ route=node1 retry=1 max=25 timeout=600
    .........
</Proxy>
3
sibnick

Sie können globale Zeitüberschreitungen oder virtuelle Hosts vermeiden, indem Sie die Proxy-Zeitüberschreitungen in der ProxyPass-Direktive wie folgt angeben:

ProxyPass /svc http://example.com/svc timeout=600
ProxyPassReverse /svc http://example.com/svc timeout=600

Beachten timeout=600 Sekunden.

Dies funktioniert jedoch nicht immer, wenn Sie über einen Lastenausgleich verfügen. In diesem Fall müssen Sie die Timeouts an beiden Stellen hinzufügen (getestet in Apache 2.2.31).

Beispiel für Load Balancer:

<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

Eine Randnotiz: das timeout=600 auf ProxyPass war nicht erforderlich, wenn Chrome war der Client (ich weiß nicht warum), aber ohne diese Zeitüberschreitung auf ProxyPass Internet Explorer (11) bricht die Meldung ab, dass die Verbindung vom Server zurückgesetzt wurde.

Meine Theorie ist, dass die:

ProxyPass Timeout wird zwischen dem Client (Browser) und dem Apache verwendet.

BalancerMember Timeout wird zwischen dem Apache und dem Backend verwendet.

Wenn Sie Tomcat oder ein anderes System verwenden, möchten Sie möglicherweise auch auf die HTTP Connector-Zeitüberschreitungen achten.

3
bhantol

sie sollten in der Lage sein, dieses Problem durch einen Timeout- und einen ProxyTimeout-Parameter zu beheben, der auf 600 Sekunden festgelegt ist. Es funktionierte für mich, nachdem ich eine Weile gekämpft hatte.

2
tallguy

Ich vermute, Sie verwenden mod_proxy_http (oder Proxy-Balancer).

Sehen Sie in Ihren Tomcat-Protokollen nach (localhost.log oder catalina.log). Ich vermute, dass in Ihrem Web-Stack eine Ausnahme auftritt, die den Socket sprudelt und den Socket schließt, mit dem der Tomcat-Mitarbeiter verbunden ist.

2
Dave Cheney

Höchstwahrscheinlich sollten Sie den Timeout-Parameter in Apache conf erhöhen (Standardwert 120 Sek.)

1
sibnick

Ich weiß, dass dies diese Frage nicht beantwortet, aber ich bin hierher gekommen, weil ich den gleichen Fehler mit nodeJS-Server hatte. Ich stecke lange fest, bis ich die Lösung gefunden habe. Meine Lösung fügt nur Schrägstrich oder /in end of proxyreserve Apache.

mein alter Code ist:

ProxyPass / http://192.168.1.1:3001
ProxyPassReverse / http://192.168.1.1:3001

der richtige Code lautet:

ProxyPass / http://192.168.1.1:3001/
ProxyPassReverse / http://192.168.1.1:3001/