Wie kann ich Apache-Timeouts debuggen?

13

Ich verwende eine PHP-Webanwendung auf einem Apache 2.2-Server (Ubuntu Server 10.04, 8x2GHz, 12Gb RAM) prefork. Jeden Tag erhält Apache ungefähr 100.000 bis 200.000 Anfragen, von denen ungefähr 100.000 bis 200.000 das Timeout-Limit erreichen (also ungefähr einer von tausend Anfragen). Nahezu alle anderen Anfragen werden weit unterhalb des Timeouts bearbeitet.

Was kann ich tun, um herauszufinden, warum dies passiert? Oder ist es normal, dass einige kleine Teile aller Anfragen abgelaufen sind?

Das habe ich bisher gemacht:

Fordert Antwortzeit an

Wie zu sehen ist, gibt es nur sehr wenige Anfragen, die zwischen dem Zeitlimit und einer angemesseneren Anfrage liegen. Derzeit ist das Zeitlimit auf 50 Sekunden festgelegt, zuvor war es auf 300 Sekunden festgelegt, und es war immer noch dieselbe Situation mit einigen Zeitlimits und einer großen Lücke zu den anderen Anforderungen.

Alle Anfragen, bei denen eine AJAXZeitüberschreitung eintritt, sind Anfragen, aber die überwiegende Mehrheit von ihnen. Vielleicht ist das eher ein Zufall. Der Apache-Rückkehrcode lautet 200, aber das Zeitlimit ist eindeutig erreicht. Sie stammen aus einer Vielzahl unterschiedlicher IPs.

Ich habe mir die Anfragen angesehen, die abgelaufen sind, und es gibt nichts Besonderes an ihnen, wenn ich die gleichen Anfragen mache, gehen sie in weit weniger als einer Sekunde durch.

Ich habe versucht, die verschiedenen Ressourcen zu untersuchen, um festzustellen, ob ich die Ursache finden kann, aber kein Glück. Es ist immer genügend freier Speicher verfügbar (mindestens 3 GB verfügbar), die Auslastung reicht manchmal bis zu 1,4 und die CPU-Auslastung bis zu 40%. Viele Zeitüberschreitungen treten jedoch auf, wenn die Auslastung und die CPU-Auslastung niedrig sind. Schreib- / Lesevorgänge auf der Festplatte sind tagsüber ziemlich konstant. Es gibt keine Einträge im langsamen MySQL-Abfrageprotokoll (festgelegt, um etwas über 1 Sekunde zu protokollieren). Bei einer No-Anfrage werden so viele Datenbank-Schreib- / Lesevorgänge ausgeführt.

Antwortzeit mit Systemlast / CPU anfordern

Blau ist die CPU-Auslastung, die mit 40% am höchsten ist, Kastanienbraun ist mit 1,4 am höchsten. Wir können also sehen, dass es auch bei geringer CPU-Auslastung zu Timeouts kommt (die 10-Sekunden-Spitzen entsprechen gut der CPU-Auslastung, aber das ist ein weiteres Problem. Ich habe größere Hoffnungen, herauszufinden, was diese verursachen könnte).

Es gibt keine Fehler im Apache-Fehlerprotokoll und ich habe nicht gesehen, dass es mehr als 200 aktive Apache-Prozesse erreicht.

Server Einstellungen:

Timeout 50 
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 2

<IfModule mpm_prefork_module>
    ServerLimit     350
    StartServers        20
    MinSpareServers     75
    MaxSpareServers     150
    MaxClients          320
    MaxRequestsPerChild 5000
</IfModule>

Aktualisieren:

Ich habe auf Ubuntu 12.04.1 aktualisiert, nur für den Fall, keine Änderung. Ich habe mod_reqtimeout mit folgenden Einstellungen hinzugefügt:

RequestReadTimeout header=20-40,minrate=500
RequestReadTimeout body=10,minrate=500

Jetzt treten fast alle Zeitüberschreitungen nach 10 Sekunden auf, eine oder zwei nach 20 Sekunden. Ich nehme an, dass es die meiste Zeit darum geht, den problematischen Anfragetext zu erhalten? Der Anforderungshauptteil sollte niemals größer als ein paar hundert Bytes sein. Ich habe den Netzwerkverkehr pro Sekunde überwacht und er wird nie höher als 1 Mbit / s, und es werden keine Rxerrs oder Rxdorps angezeigt, wenn man bedenkt, dass sich der Server auf einer 1 Gbit / s-Leitung befindet, wie es nicht klingt die HopelessN00b gepostet über. Könnte es nur ein Fall von schlechten Benutzerverbindungen sein?

Für die Spitzen jede Stunde (sie scheinen ein bisschen herumzudriften, in den obigen Grafiken sind sie 33 Minuten nach der vollen Stunde, jetzt sind sie 12 Minuten nach der vollen Stunde), habe ich versucht zu sehen, ob periodisch etwas läuft ( crons etc) aber nichts gefunden. PHP Garbage Collection wird zweimal pro Stunde ausgeführt, aber nicht zum Zeitpunkt der Spikes. Ich habe immer noch versucht, es zu deaktivieren, aber es macht keinen Unterschied.

Ich habe dstat mit --top-cpu und top verwendet, um die Prozesse zum Zeitpunkt der Spitzen zu untersuchen, und alles, was angezeigt wird, ist, dass Apache einige Sekunden lang hart arbeitet, aber kein anderer Prozess verwendet eine signifikante CPU.

Ich habe ein vergrößertes Diagramm der Spitzen erstellt: Antwortzeit für gezoomte Anforderung

Für mich sieht es so aus, als ob Apache für einige Sekunden anhält und dann hart arbeitet, um die Anforderungen zu verarbeiten, die während des Anhaltens eingegangen sind. Was könnte einen solchen Stillstand verursachen, oder interpretiere ich ihn falsch?

Leon
quelle
1
Ich wollte ein paar Grafiken über die Anfragen posten, aber mein Repräsentant ist zu niedrig.
Leon

Antworten:

4

Das erste, was ich in Ihrem ersten Diagramm bemerke, scheint eine stündliche Verlangsamung (etwa 40 Minuten nach der vollen Stunde) zu sein, die möglicherweise zu dem Problem beiträgt. Sie sollten einen Blick auf die Taskplaner in der OS / Datenbank werfen.

Basierend auf den von Ihnen gelieferten Daten würde mein nächster Schritt darin bestehen, die Häufigkeit der Antwortzeiten (Anzahl der Antworten auf der Y-Achse im Verhältnis zur Dauer auf der X-Achse) zu untersuchen, aber nur URLs einzuschließen, bei denen das Timeout auftritt (oder vorzugsweise jeweils eine URL) ). Auf einem typischen System sollte dies einer Normal- oder Poisson-Verteilung folgen - die Anfragen, bei denen das Zeitlimit überschritten wird, können einfach Teil des Tails sein. In diesem Fall müssen Sie sich auf die allgemeine Optimierung konzentrieren. OTOH Wenn die Distribution bimodal ist, müssen Sie irgendwo in Ihrem Code nach Konflikten suchen.

symcbean
quelle
Vielen Dank für Ihre Antwort. Ich schaue nach, was die stündlichen Verlangsamungen verursachen könnte. In der Zwischenzeit habe ich ein Frequenzdiagramm der Daten erstellt, die ich bereits habe. Dies ist nur eine der URLs, bei denen ein Timeout-Problem auftritt (die anderen sehen jedoch sehr ähnlich aus): leela.kikora.no/apache_hist_show.png Die Anzahl der Timeouts ist im Vergleich zu denjenigen, die weniger als 10 Sekunden dauern, sehr gering als ob es nicht Teil des Schwanzes wäre. Auf der anderen Seite könnte es aber auch so aussehen, da sie alles darstellen, was mehr als 50 Sekunden gedauert hätte.
Leon
3

Ich habe einen anderen Gedanken dazu, basierend auf der Tatsache, dass Sie eine große Anzahl von Anfragen pro Tag erhalten und anscheinend nur während der Stoßzeiten (von den von Ihnen geposteten Bildern) Zeitüberschreitungen haben.

Es gibt einen Beitrag im ServerFault-Blog.Per Second Measurements Don't Cut It Ist es möglich, dass einige dieser Anforderungen auf dasselbe Problem stoßen, auf das das ServerFault-Team gestoßen ist?

Wir haben festgestellt, dass wir Pakete auf 1-Gbit / s-Schnittstellen mit Raten von nur 10-30 MBit / s ziemlich häufig verwerfen, was unsere Leistung beeinträchtigt. Dies liegt daran, dass die Rate von 10-30 MBit / s tatsächlich die Anzahl der pro 5 Minuten übertragenen Bits ist, die in eine 1-Sekunden-Rate umgewandelt wurden. Wenn wir näher an Wireshark herangehen und eine Millisekunden-E / A-Grafik verwenden, sehen wir, dass die 1-Mbit / Millisekunden-Rate der sogenannten 1-Gbit / s-Schnittstellen häufig geplatzt ist.

HopelessN00b
quelle
Interessant, ich werde es mir ansehen. Ich habe mod_reqtimeout aktiviert und auf RequestReadTimeout-Header = 20-40, minrate = 500 und RequestReadTimeout-Body = 10, minrate = 500 gesetzt, und fast alle Timeouts treten jetzt nach 10 Sekunden auf. Ich nehme das an, um zu bedeuten, dass der Anforderungshauptteil zu lange dauert (der Hauptteil sollte nie mehr als ein paar hundert Byte groß sein), sodass entweder einige meiner Benutzer schlechte Verbindungen haben oder, wie Sie sagen, auf der Seite meines Servers eine Überlastung vorliegt.
Leon