Dieser Artikel stellt hauptsächlich das Verständnis der beiden Ausführungsmethoden von PHP-Speicherüberlauf, Befehlszeile und Webdienst vor. Jetzt kann ich ihn mit Ihnen teilen
Während des Entwicklungsprozesses gab eine bestimmte Schnittstelle aufgrund einer übermäßigen Menge an aus der Datenbank gelesenen Daten den Status 200 zurück, aber keine Antwortdaten. Das PHP-Fehlerprotokoll enthielt die folgenden Informationen: Schwerwiegender PHP-Fehler: Erlaubte Speichergröße von 134217728 Bytes erschöpft.
Natürlich ist dies ein Fehler, der durch „Out of Memory“ verursacht wird, aber was mich verwirrt, ist, dass es keine Ausgabe im Geschäftsprotokoll (application.log) des Yii-Frameworks gibt und es keinen Stack Trace auf der Seite gibt . Fehlermeldung, daher haben wir die Ursache ermittelt.
Die Gründe sind wie folgt. Schauen wir uns zunächst den Kerncode der Datei CApplication.php des Yii-Frameworks an:
public function run() { if($this->hasEventHandler('onBeginRequest')) $this->onBeginRequest(new CEvent($this)); register_shutdown_function(array($this,'end'),0,false); $this->processRequest(); if($this->hasEventHandler('onEndRequest')) $this->onEndRequest(new CEvent($this)); }
wird verwendet register_shutdown_function
, um einen Rückruf zu registrieren, wenn die Anfrage abnormal beendet wird. Normalerweise tritt in PHP eine Ausnahme auf. Die end()
-Methode wird zurückgerufen, wenn das Skript beendet wird. Sie können onEndRequest
im Listener des error_get_last()
-Ereignisses verwenden.
Wenn jedoch OOM auftritt, führt der Linux Out Of Memory Killer kill -9 aus, um das SIGKILL-Signal zu senden. Gemäß den Anweisungen im PHP-Handbuch kann das SIGKILL-Signal nicht erfasst und abgefangen werden wird ohne Bereinigungscode direkt beendet, sodass die register_shutdown_function
-Methode nicht funktioniert und es natürlich keine nachfolgenden Protokollierungs-, Fehlerseitenanzeige- usw. Prozesse gibt.
Außerdem ist mir während der Entwicklung ein Phänomen aufgefallen: Beim Zugriff über das Web tritt OOM auf, bei der Ausführung über die Konsole wird jedoch kein Fehler gemeldet.
Es ist ersichtlich, dass es einen Unterschied zwischen den beiden Methoden gibt. Beim Zugriff auf das Web wird der PHP-Skriptprozess durch PHP-FPM gestartet und auch durch die FPM-Konfigurationsdatei in / eingeschränkt. etc/php-fpm.d hat ein Limit von php_admin_value[memory_limit] = 128 MB. Eine einfache Erhöhung des „memory_limit“ in der php.ini hat also beim Zugriff über das Web keine Auswirkung.
Die Ausführung im Konsolenmodus erfolgt nicht über PHP-FPM, daher ist sie nur durch die in php.ini konfigurierten Speicherparameter und das in der Entwicklungsmaschine konfigurierte „memory_limit“ => 512M => 512M begrenzt, also wird es so sein Es wird kein OOM generiert.
Hier ist eine Frage: Wie verwaltet PHP-FPM den PHP-Prozess? Verwendet PHP-FPM wirklich kill -9, um den PHP-Skriptprozess abzubrechen?
Anbei ist die Aufrufbeziehung zwischen Webserver, PHP-FPM und PHP-Skript:
Die Anforderung geht zuerst auf den Webserver (z. B. Nginx). und Nginx verteilt die Anfrage (je nach Serverknoten-, Standortknoten- usw. Konfiguration):
Das Anfordern statischer Ressourcen erfordert keine FastCGI-Verarbeitung und geht direkt zum entsprechenden Dateispeicherort
Dynamische Anfragen erfordern Für die PHP-Codeverarbeitung müssen Sie die Anfrage an das Programm übergeben, das das FastCGI-Protokoll (PHP-FPM) implementiert
Sie Sie können solche Konfigurationsinformationen in Nginx sehen: „fastcgi_pass 127.0.0.1:9000 ;“, führen Sie den Befehl „lsof -i:9000“ aus und Sie können sehen, dass Port 9000 zufällig der PHP-FPM-Prozess ist.
Nginx übergibt die Anforderungsinformationen an PHP-FPM, PHP-FPM weist einen Worker-Prozess zur Verarbeitung zu, der Worker-Prozess registriert Variablen $_GET/$_POST
usw., greift entsprechend den Anforderungsinformationen auf die angegebene PHP-Skriptdatei zu, und verwendet dann die PHP-Interpreter-Implementierung.
(Mein Verständnis ist: entspricht dem Starten des PHP-Interpreters durch PHP-FPM, ein bisschen wie dem Ausführen des Befehls php -f script.php
)
Die vom Netzwerk angeforderten Informationen werden Schicht für Schicht weitergeleitet und erreichen schließlich PHP. Daher können in PHP verschiedene Parameter dieser HTTP-Anfrage im Code abgerufen werden.
Nginx teilt PHP-FPM mit, welches PHP-Skript ausgeführt werden soll. In der Nginx-Konfiguration ist eine Zeile zu sehen:
fastcgi_param SCRIPT_FILENAME /home/dev_user/www/xxx/webroot/index.php;
Wenn Sie keine PHP-Datei angeben, wird die Standardkonfiguration verwendet. Versuchen Sie, die Datei im Stammverzeichnis zu verwenden. Das Rahmenprogramm wird in index.php gestartet und das Rahmenwerk findet den entsprechenden Controller und die entsprechende Aktion, um die eigentliche Geschäftslogik zu vervollständigen.
Das obige ist der detaillierte Inhalt vonVerständnis von PHP-Speicherüberlauf, Befehlszeilen- und Webdienst-Ausführungsmethoden. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!