fragen stichworte

Apache-Speicherprobleme

Ich bin mir sicher, dass dies wahrscheinlich schon früher gefragt wurde, aber ich möchte sicherstellen, dass ich die richtigen Informationen bekomme.

Ich verwende eine 360-Linode-Box mit Debian 5 und Apache 2.2. Ich habe alles selbst zusammengestellt (kein apt-get). Hin und wieder (einmal alle paar Wochen?) Würde mein Server zufällig "abstürzen": Er würde bis zu 100% CPU (wirklich 400%, aber Sie wissen was ich meine) schießen und die Box übergeben. Sie konnten SSH nicht sehen, um zu sehen, was das Problem war, und der Server nahm keine Verbindungen mehr an. Die einzige Möglichkeit, dies zu beheben, bestand darin, die Box neu zu starten.

Vor kurzem begann es mit relativer Häufigkeit: 24 Stunden, 12 Stunden, 10 Stunden, 8, 6, 4. Endlich konnte ich einen Blick erhaschen, bevor es vor zwei Tagen einsperrte. Ich bemerkte, dass die Festplatten-IO erhöht war und dass kaum noch RAM vorhanden war! Außerdem gab es eine Bootlast von httpd-Prozessen, die mit 3-4% RAM ausgeführt wurden. Und mit dem Boot, ich meine, als ich ein PS gemacht habe, nahmen sie den gesamten Bildschirm ein. Wenn Sie einen Bildlauf durchgeführt haben, nahmen sie den gesamten Puffer für meinen SSH-Client in Anspruch.

Ich habe also einige Änderungen an meinem Code vorgenommen und dachte, dass etwas nicht richtig schließt. Ich behebte Speicherprobleme in meinem PHP, stellte die detailliertere Fehlerprotokollierung ein und behebte eine Reihe von Fehlern. Dies schien bis zu einem gewissen Grad zu helfen. Die Abstürze gingen etwa alle 24 Stunden zurück.

Ich bin überzeugt, dass dies darauf zurückzuführen ist, dass zu wenig Speicherplatz vorhanden ist und die Anzahl der Treffer, die ich erhalte, meinen Server in den Swap stößt. Da es so viele Anfragen gibt, die den Swap treffen, schießt das Disk-IO durch das Dach, wodurch meine CPU-Auslastung durch das Dach schiesst und mein Server blockiert.

Hier habe ich versucht, das Problem zu beheben: Ich habe Nachforschungen angestellt und festgestellt, dass ich wahrscheinlich Prefork verwenden sollte. Ich habe mich in meiner Konfiguration umgesehen und konnte kein ServerLimit oder MaxClients oder ähnliches finden. Daher fügte ich einige "Standardwerte" hinzu und mein Server weigerte sich, irgendwelche Verbindungen anzunehmen. In der Tat haben die prefork-Werte den gesamten eingehenden http-Verkehr blockiert, indem sie die Verbindung verschluckten (möglicherweise, weil mein Server prefork? Idk nicht verarbeiten kann).

Wie ich es sehe, war mein Server in Ordnung, abgesehen von all diesen Apache-Prozessen, die ständig aufgehängt wurden und Speicher verloren gingen. Gibt es eine Möglichkeit, ein Timeout für Apache-Prozesse festzulegen oder deren Anzahl zu begrenzen? Es scheint ziemlich dumm zu sein, dass die beste Lösung Prefork ist. Ich muss mir vorstellen, dass es einen besseren Weg gibt.

Danke Jungs

antworten

Es scheint, dass Sie lernen, wie schwer es ist, dass PHP ein Speicherfresser ist und nicht besonders skalierbar ist.

Einige Vorschläge in keiner bestimmten Reihenfolge:

Wenn Sie immer noch einen Speicherleck vermuten, setzen Sie MaxRequestsPerChild auf einen wirklich niedrigen Wert.

Erwägen Sie den Kauf von mehr Arbeitsspeicher. 360 MB sind heutzutage wirklich nicht viel.

Versuchen Sie, eine durchschnittliche Größe des httpd-Prozesses zu ermitteln, indem Sie ps oder top ausführen und dann MaxClients so einstellen, dass alles immer in den Speicher passt. Das Austauschen ist eine Todesspirale. Je langsamer Sie die Anfragen verarbeiten, desto mehr Prozesse muss der Apache zwingen, um noch mehr Speicher zu verwenden.

Wenn Sie php als Modul in Apache einrichten, wird es für jede Anforderung geladen, sei es ein Skript oder eine statische Datei (ein Image oder eine css oder .js oder whatnot). Erwägen Sie die Bereitstellung statischer Inhalte von einem separaten Server oder verwenden Sie fastcgi oder einen Reverse-Proxy wie nginx, damit Apache nur php bereitstellt, um die Anzahl der fetten php-Instanzen zu begrenzen, die Sie im Speicher aufbewahren müssen.

Wenn Sie wirklich wenig Speicher haben, könnten Sie versuchen, etwas wie lighttpd oder nginx mit php als fastcgi-Prozess auszuführen. Ich habe nginx nicht so oft verwendet, aber ich benutze lighttpd allot und hat einen extrem geringen Speicher/CPU-Aufwand.

Lighttpd und PHP über das Fastcgi-Tutorial

Ich vermute, dass Ihr Computer mit zu wenig Speicher arbeitet. In meiner Erfahrung hat jeder laufende Apache-Prozess das Potenzial, viel Speicher zu verbrauchen. Wenn Sie php als Modul in Apache ausführen, schauen Sie in Ihrer php.ini nach, was der Wert für memory_limit = ist. Ich hatte 128M, was ziemlich viel ist, wenn nur 10 Apache-Prozesse laufen. Sie nehmen diese Menge möglicherweise nicht von Anfang an an, aber wenn Ihre PHP-Anwendung über genügend Speicher verfügt oder wirklich 128 MB benötigt, können Sie Ihre Server-Limits ganz leicht erreichen.

Meine Empfehlung lautet: Physical Ram geteilt durch memory_limit entspricht max_procs

Haben Sie ein Datenbank-Backend, zu dem Sie eine Verbindung herstellen? Häufig passiert Folgendes, wenn einige Abfragen langsamer werden und Sie Apache-Prozesse zu sichern beginnen. Angesichts der geringen Menge an Arbeitsspeicher auf Ihrer Linode wird es zu einem Schneeball und Stürzen, wodurch die CPU und die Ladung hochschnellen.

Sie haben erwähnt, dass Sie das Worker-Modell verwenden. Dies ist in Ordnung, wenn Sie zu 100% sicher sind, dass alle Module, die Sie in PHP verwenden, Thread-sicher sind. Das eigentliche PHP-Installationshandbuch empfiehlt jedoch, es nicht zu verwenden (php-Handbuch) ... Unabhängig davon, mit welchem ​​Modell Sie arbeiten, müssen Sie sicherstellen, dass Sie sie richtig einstellen. Ein guter Startpunkt ist Tuning LAMP-Systeme. Wenn MaxClients nicht richtig eingestellt ist, kann es vorkommen, dass Apache zum Absturz des Systems führt, da der gesamte Speicherplatz während eines Verkehrsaufkommens an Ihrem Standort belegt wird.