Mein Setup: Ich habe 3 nahezu identische Webserver-Computer, die dieselbe hoch geladene dynamische Website mit einfachem Lastausgleich über DNS bedienen. Der Dienst arbeitet seit über zwei Jahren mit derselben Apache-Konfiguration: Apache2, PHP5, Ubuntu 8.04 Linux 2.6.24-29-Server.
Mein Problem: Seit ungefähr zwei Wochen habe ich Probleme mit dieser Konfiguration. Fast jeden Tag habe ich einen kleinen Moment für ungefähr 5 Minuten, in dem die Website nicht erreichbar ist. Ich kann mich immer noch über ssh bei den Servern anmelden. Wenn ich renne htop
, sehe ich, dass die Maschine einfach nichts tut. Ich habe ungefähr 1000 Apache-Prozesse ausgeführt, aber keine CPU-Aktivität.
Ich habe den Apache mod_status verwendet, um diese Situation zu debuggen. Die Prozessanzeige sieht folgendermaßen aus:
_C.___K_______________________R._______.__K_K____K___C_______.__
_______C__________.___________________________________.________C
_.____K__________K___K_WK_____._K_____________________________._
W______K__________K________.____________________._______C_______
_C_.__K__K____.._.._____________________________________C_______
_R___________K___.______C________.C_________.______._____C______
____________KKC____K_____K__WC_________________C_____.__.____.__
_____________________C_________K______.____C______._____________
_.___C____.___.___________________________.K______.____K________
W__.___________________C.__.____K________K_______R_._.__._______
__C__C_.__________C__C_______._____W______________C_.___C_______
____.______C_____________C________.____C____________.________._K
__.__________.K_____________K_________._____C____.K__________KW_
__K.W________R_________._______.___W___________.____.__K_____W__
W___.___..________W____K
Scoreboard Key:
"_" Waiting for Connection, "S" Starting up, "R" Reading Request,
"W" Sending Reply, "K" Keepalive (read), "D" DNS Lookup,
"C" Closing connection, "L" Logging, "G" Gracefully finishing,
"I" Idle cleanup of worker, "." Open slot with no current process
Die meisten Prozesse warten also nur auf die Verbindung. Nach ungefähr 5 Minuten wird sich die Situation wieder normalisieren: Ich habe auf jeder Maschine die wenigsten Prozesse, die meisten Mitarbeiter haben den Status "." (dh sie sind offen für die Bearbeitung einer Anfrage) und natürlich ist die Website erreichbar!
Ich versuche also, etwas in den Protokollen zu finden, aber es gibt einfach nichts ... Das Apache-Zugriffsprotokoll ist ungefähr 4 Minuten lang still, das gleiche gilt für das Fehlerprotokoll. Ich kann auch nichts falsches in anderen Systemprotokollen herausfinden.
Die Situation ist auf allen 3 Webservern gleich (alle haben gleichzeitig diese Lastspitze und den nicht reagierenden Zustand), daher denke ich nicht, dass dies hardwarebezogen ist. aber ich denke, dies könnte mit einem Netzwerkproblem (TCP) zusammenhängen.
irgendwelche Ideen?
EDIT: einige weitere Informationen, die ich gerade entdeckt habe:
Es ist gerade wieder passiert und ich konnte überprüfen, ob ich bei diesem Problem auch keine lokale Verbindung herstellen kann.
Ich habe einige Verbindungsstatistiken mit dem folgenden Befehl erstellt, nachdem dies geschehen ist: netstat -an|awk '/tcp/ {print $6}'|sort|uniq -c
- 109 CLOSE_WAIT
- 2652 GEGRÜNDET
- 2 FIN_WAIT1
- 11 LAST_ACK
- 12 HÖREN
- 91 SYN_RECV
- 1 SYN_SENT
- 16 TIME_WAIT
Wenn ich den gleichen Befehl einige Zeit später ausführe, habe ich ungefähr Folgendes:
- 4 SCHLIESSEN
- 108 GEGRÜNDET
- 18 FIN_WAIT1
- 182 FIN_WAIT2
- 37 LAST_ACK
- 12 HÖREN
- 50 SYN_RECV
- 11276 TIME_WAIT
In der normalen Situation habe ich also nur 100-200 offene Verbindungen von Clients, die in diesem Moment von Apache behandelt werden. Wenn ich diesen "Absturz" habe, habe ich viel mehr Verbindungen. Wie lässt sich das am besten analysieren?
EDIT2: Die wichtigen Zeilen in apache2.conf sind:
KeepAlive On
MaxKeepAliveRequests 20
KeepAliveTimeout 1
<IfModule mpm_prefork_module>
ServerLimit 920
StartServers 30
MinSpareServers 80
MaxSpareServers 120
MaxClients 920
MaxRequestsPerChild 700
</IfModule>
Es ist eine Apache2-Prefork mit php_mod.
Der Server verfügt über 8 GB RAM und eine 4 GB Swap-Partition.
tcpdump
hilft Ihnen ein Traffic Dump ( ) dabei, das Problem zu lösen ... Übrigens, wie lauten Ihre Speichernutzung und Ihre Firewall-Richtlinien?Antworten:
Sie sollten den erweiterten Status von mod_status ( http://httpd.apache.org/docs/2.2/mod/mod_status.html#extendedstatus ) aktivieren , um die aktuellen Hosts und Anforderungen zu überwachen, die verarbeitet werden. Ich denke, es gibt ein Skript / Seiten (s), die zu viel Zeit benötigen, um die Verbindung freizugeben, und die Verbindungen stapeln.
quelle
Erstens: Überprüfen Sie Ihr
Max open files
Limit für den Prozess. Eine aktive Socket-Verbindung gilt als geöffnete Datei.cat /proc/###/limits
ist eine gute Möglichkeit, den effektiven Wert für einen anderen Prozess zu überprüfen. Sie können eine Liste der geöffneten Dateienlsof -p ###
abrufen, wobei ### die Prozess-ID Ihres Webservers ist. Sie können vergleichenlsof -p ### | wc -l
, um zu sehen, wie nahe Sie dem Limit kommen. Sie sollten auch Nachrichten im Fehlerprotokoll von Apache sehen, wenn Sie das Limit erreichen.Sie benötigen ein Dateihandle für jede Socket-Verbindung sowie für jedes CGI-Skript oder jede Datendateireferenz. Für 920 MaxClients sollten Sie mindestens 4.000 Dateien für den httpd-Prozess konfigurieren. Sie können die Anzahl der Dateien erhöhen, indem Sie eine Datei in /etc/security/limits.d/ mit dem folgenden Inhalt hinzufügen. Stellen Sie sicher, dass der Benutzername mit dem übereinstimmt, den Sie für Ihren Webserver verwenden.
Zweitens: Wenn die Erschöpfung des Ports Ihr Problem ist, können Sie einige IP-Einstellungen in /etc/sysctl.conf anpassen. (Beginnend mit
net.ipv4.tcp_fin_timeout
). Dies ist normalerweise nur bei vielen sehr kleinen Verbindungen ein Problem. Viele TIME_WAIT-Sockets sind ein Indikator dafür, aber dies zeigt nur dann eine Erschöpfung des Ports an, wenn Fehler im Syslog überpossible SYN flooding
und auftretenSending cookies
. Sie sollten auch sicherstellen, dass sich Ihr Server hinter einer Firewall befindet, die böswillige SYN-Angriffe verhindern kann.quelle
Beachten Sie auch, dass im Prefork-MPM für jeden Prozess PHP im Speicherbereich vorhanden ist (wie lautet die Einstellung für das Speicherlimit?). Möglicherweise möchten Sie versuchen, zum Worker-MPM zu wechseln, für den möglicherweise ein etwas anderes PHP-Modul erforderlich ist.
Auch einen Remote-Ohrring wert, um Ihre Apache-Konfiguration von Fremdmodulen zu kürzen
Nach meiner Erfahrung werden solche Dinge durch Dinge wie einen Suchmaschinen-Crawler oder Dinge wie ARP-Konflikte ausgelöst. Oder Verkehrsaufkommen in einem verwandten Teil des Netzwerks.
Vielleicht finden Sie 'sar' nützlich ... nicht das freundlichste, aber sicherlich nützlich.
Möglicherweise auch io verwandt. Sar kann Ihnen sagen (wenn Sie es so konfigurieren, dass es die Festplattenaktivität aufzeichnet), wie hoch die durchschnittliche Wartezeit ist. Sie können auch die E / A-Wartezeit oben anzeigen (dies ist ein Prozentsatz, lesen Sie, was dies tatsächlich bedeutet). Dies kann von Bedeutung sein, wenn Sie ein SAN oder eine virtuelle Umgebung verwenden.
quelle