Apache ist in den letzten Tagen außer Kontrolle geraten und hat MySQL zweimal zum Absturz gebracht. Alles begann, als ich eine WordPress-Website migrierte, die auch ein phpBB-Forum enthält.
Ich habe nicht viel Erfahrung in der Serveradministration, daher war es für mich sehr schwierig, die Ursache des Problems zu ermitteln. Als ich bemerkte, dass MySQL ausgefallen war, führte ich TOP aus und sah, wie meine Systemlast auf 98,00 anstieg. Der Server betreibt 10 V-HOSTS, die alle eine gesunde Menge an Datenverkehr erhalten, sodass ich offensichtlich viele laufende Apache-2-Prozesse sah.
Die hohe Serverlast hielt 10 Minuten lang an und kehrte dann in den Normalzustand zurück. Zu diesem Zeitpunkt konnte ich keinen Anstieg des Netzwerkverkehrs feststellen.
Leider war die MySQL-Fehlerprotokollierung deaktiviert (sie ist jetzt wieder aktiviert), daher gibt es hier keine Hinweise. Aber ich bin ziemlich sicher, dass es daran liegt, dass Apache alle Ressourcen verbraucht hat, sodass die MySQL-Prozess-ID beendet wurde.
Meine Fragen sind:
Wenn dies das nächste Mal passiert – wie kann ich herausfinden, was die Systemlastspitze verursacht? Könnte es ein PHP-Skript sein, das verrücktgespielt hat? Könnte es ein DDOS-Angriff sein?
Gibt es eine Möglichkeit, MySQL nach einem Absturz automatisch neu zu starten?
Ich habe jetzt installiert htop
. Könnte das nützlicher sein als top
?
Hier meine Serverstatistiken:
m1.xlarge (8 ECUs, 4 vCPUs, 15 GiB memory, 4 x 420 GiB Storage Capacity)
Ubuntu Server 12.04.3 LTS
Antwort1
MySQL protokolliert möglicherweise immer noch nichts, weil es wahrscheinlich vom System aufgrund von Systemspeicherdruck durch Apache-Untersysteme kurzerhand beendet wird. Eine Spur davon sollte in /var/log/syslog vorhanden sein.
MySQL sollte bei einem Absturz oder einer erzwungenen Beendigung versuchen, sich selbst neu zu starten, aber wenn nicht genügend Speicher verfügbar ist, kann es das nicht tun... und dieser zweite Fehler wird von mysqld_safe nicht als „Absturz“, sondern als „Startverweigerung“ angesehen, sodass es keinen weiteren Versuch unternimmt. Der fehlgeschlagene Neustartversuch wird von Administratoren häufig als „Absturz“ missverstanden, da die Art des ursprünglichen Fehlers hinter einer leicht zu übersehenden Meldung im MySQL-Fehlerprotokoll verborgen ist:
mysqld_safe Number of processes running now: 0
SehenPost-Mortem-Bericht zum InnoDB-Absturzfür einen Umstand, der, wie ich vermute, Ihrem ähnlich ist.
Die scheinbar einfache Antwort auf die Frage „Warum?“ lautet, dass Sie aufgrund von Apache und MySQL, Ihrer Auslastung und Ihren aktuellen Konfigurationen nicht genügend Arbeitsspeicher auf Ihrem Computer haben und dass es einen Wendepunkt in Bezug auf die Verkehrslast gibt, der diesen Zustand hervorruft.
Apache bedient jede gleichzeitige Browseranfrage von einem untergeordneten Prozess aus. Wenn also die Anzahl gleichzeitiger Verbindungen steigt, erhöht sich auch die Anzahl der untergeordneten Prozesse. Sie müssen diesen Wert zunächst in der Apache-Konfiguration begrenzen, damit Sie verstehen, was die tatsächliche Ursache für den Anstieg gleichzeitiger Verbindungen ist. Handelt es sich einfach um eine starke, aber legitime Verkehrsspitze? Eine Art Denial-of-Service-Angriff? DB-Abfragen, die Anfragen verzögern, weil sie zu lange laufen? Etwas, das optimiert werden muss?
http://httpd.apache.org/docs/2.2/mod/mpm_common.html#maxclients
Die Begrenzung gleichzeitiger Apache-Prozesse sollte helfen, dies zu verhindern. Aber um es klar zu sagen: Es ist naiv zu glauben, dass dies die vollständige Lösung ist. Deshalb möchte ich das auch nicht unterstellen. Sobald die Prozesse auf ein vernünftiges oder zumindest sichereres Maß begrenzt sind, können Sie mit der Ermittlung dessen fortfahren, was wirklich vor sich geht. (Es gibt andere Einschränkungsmaßnahmen bei Apache, aber das ist nicht mein Fachgebiet.)
Die „beste Vorgehensweise“ besteht natürlich darin, Ihre Datenbank auf unterschiedlicher Hardware auszuführen, damit die Anwendung sie nicht zerstören kann. Obwohl es auf den ersten Blick effizienter erscheint, die „Auslastung“ einer Maschine durch gemeinsame Nutzung zu maximieren, ist dies eine falsche Sparmaßnahme. Der Großteil des von MySQL in einer typischen Arbeitslast verwendeten Speichers wird beim Start zugewiesen und so lange gehalten, wie MySQL Server ausgeführt wird. Die Anforderungen an die CPU werden sich wahrscheinlich die Spitzenzeiten für MySQL und Apache teilen, da sie letztendlich dieselbe Last bedienen. Sie könnten tatsächlich mit zwei m1.large-Maschinen anstelle der einzelnen m1.xlarge besser dran sein, und die Kosten wären dieselben, da die kleinere genau halb so viel kostet wie die größere … selbst wenn Sie den zusätzlichen Rabatt bereits im Voraus bezahlt haben.Diese Änderung kann erreicht werden.
Antwort2
Sie müssen einige Punkte überprüfen:
-Überprüfen Sie /var/log/messages: oomkiller kann den MySQL-Prozess beenden, wenn kein Speicher mehr verfügbar ist. Überprüfen Sie den RAM mit free -lm (ohne Cache).
-Wenn Sie Apache mit Prefork MPM verwenden: Überprüfen Sie die Anzahl der Prozesse. Wenn Apache eine wichtige Anzahl von Prozessen (bei hoher Arbeitslast) mit einer Verbindung zu MySQL stapelt, können die Latenz und der verwendete Speicher schnell ansteigen.
-Überprüfen Sie die Anzahl der von MySQL gestarteten Threads mit einemglobalen Status anzeigen: Es ist wichtig, die Werte „threads_cached“, „threads_created“ und „threads_running“ zu überprüfen (threads_created sollte nahe 0 liegen).
- Überprüfen Sie den von MySQL verwendeten RAM.
Antwort3
Sie könnten auch die Implementierung in Betracht ziehenCPU-Setsund das Reservieren von Ressourcen für MySQL. Das kommt dem Ausführen dieser Dienste auf unterschiedlicher Hardware am nächsten, bietet Ihnen aber dennoch die Vorteile der Wartung eines einzelnen Servers.