Maison >développement back-end >tutoriel php >Compréhension des méthodes de débordement de mémoire PHP, de ligne de commande et d'exécution de services Web

Compréhension des méthodes de débordement de mémoire PHP, de ligne de commande et d'exécution de services Web

不言
不言original
2018-05-31 16:53:252087parcourir

Cet article présente principalement la compréhension des deux méthodes d'exécution du débordement de mémoire PHP, de la ligne de commande et du service Web. Il a une certaine valeur de référence. Maintenant, je le partage avec vous. Les amis dans le besoin peuvent s'y référer

Pendant le processus de développement, en raison d'une quantité excessive de données lues dans la base de données, une certaine interface a renvoyé un statut de 200 mais aucune donnée de réponse. Le journal des erreurs PHP contenait les informations suivantes : Erreur fatale PHP : taille de mémoire autorisée de 134217728 octets. épuisé.

Évidemment, il s'agit d'une erreur causée par un débordement de mémoire (Out Of Memory), mais ce qui me laisse perplexe, c'est qu'il n'y a aucune sortie dans le journal d'activité (application.log) du framework Yii, et il n'y a pas de sortie. Stack Trace sur la page message d'erreur, nous avons donc retracé la cause.

Les raisons sont les suivantes. Regardons d'abord le code principal du fichier CApplication.php du framework Yii :

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));
}
utilisé

avant de traiter la demande d'enregistrement du rappel lorsque la terminaison anormale se produit. Normalement, PHP Lorsqu'un script anormal se termine, la méthode register_shutdown_function sera rappelée. Vous pouvez utiliser end() dans l'écouteur de l'événement onEndRequest pour obtenir cette erreur. error_get_last()

Cependant, lorsque le MOO se produit, le tueur Linux Out Of Memory exécutera kill -9 pour envoyer le signal SIGKILL. Selon les instructions du manuel PHP, le signal SIGKILL ne peut pas être capturé et intercepté. se terminera directement sans aucun code de nettoyage. Aucun des deux ne sera exécuté, donc la méthode

ne fonctionnera pas et, naturellement, il n'y aura pas de processus de journalisation ultérieur, d'affichage de page d'erreur, etc. register_shutdown_function

De plus, j'ai remarqué un phénomène lors du développement : le MOO se produira lors de l'accès via le Web, mais aucune erreur ne sera signalée lors de l'exécution via la console.

On peut voir qu'il existe une différence entre les deux méthodes. Lors de l'accès au Web, le processus de script PHP est démarré par PHP-FPM et est également limité par le fichier de configuration FPM dans /. etc/php-fpm.d a une limite de php_admin_value[memory_limit] = 128M. Ainsi, le simple fait d'augmenter la limite de mémoire dans php.ini n'a aucun effet lors de l'accès via le Web.

L'exécution en mode console ne passe pas par PHP-FPM, elle n'est donc limitée que par les paramètres mémoire configurés dans php.ini, et la memory_limit configurée dans la machine de développement => 512M => 512M, donc ce sera aucun MOO n'est généré.

Voici une question du point de vue des principes d'implémentation, comment PHP-FPM gère-t-il le processus PHP ? PHP-FPM utilise-t-il vraiment kill -9 pour tuer le processus de script PHP ?


Ci-joint la relation d'appel du serveur Web, PHP-FPM et du script PHP :

La requête entre d'abord dans le serveur Web (tel que Nginx), et Nginx distribue la requête (selon la configuration du nœud de serveur, du nœud d'emplacement, etc.) :

  1. La demande de ressources statiques ne nécessite pas de traitement FastCGI, et va directement à l'emplacement du fichier correspondant

  2. Requêtes dynamiques requises Pour le traitement du code PHP, vous devez transmettre la requête au programme qui implémente le protocole FastCGI (PHP-FPM)

Vous Vous pouvez voir ces informations de configuration dans Nginx : "fastcgi_pass 127.0.0.1:9000 ;", exécutez la commande "lsof -i:9000" et vous pouvez voir que le port 9000 se trouve être le processus PHP-FPM.

Nginx transmet les informations de la demande à PHP-FPM, PHP-FPM alloue un processus Worker pour le traitement, le processus Worker enregistre les variables

, etc., accède au fichier de script PHP spécifié en fonction des informations de la demande, puis utilise l'implémentation de l'interpréteur PHP. $_GET/$_POST (Ma compréhension est : équivalent à PHP-FPM démarrant l'interpréteur PHP, un peu comme exécuter la commande
) php -f script.php

Les informations demandées par le réseau sont transmises couche par couche et parviennent finalement à PHP, donc en PHP Différents paramètres de cette requête HTTP peuvent être obtenus dans le code.

Nginx indique à PHP-FPM quel script PHP exécuter. Une ligne est visible dans la configuration de Nginx :

fastcgi_param SCRIPT_FILENAME /home/dev_user/www/xxx/webroot/index.php;
Si vous ne spécifiez pas de fichier PHP, la configuration par défaut sera. utilisé et le répertoire racine sera essayé sous. Le programme-cadre sera démarré dans index.php, et le framework trouvera le contrôleur et l'action correspondants pour compléter la logique métier réelle.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn