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:
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 AJAX
Zeitü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.
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:
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?