Découvrez ce que fait réellement le processus Apache à forte utilisation du processeur?

18

Nous avons actuellement quelques problèmes avec notre serveur où, par intermittence, nous semblons obtenir des processus apache qui s'exécutent et s'exécutent, occupant 100% du processeur.

Lors de l'exécution en haut, nous voyons ce qui suit:

PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
20788 www-data  20   0  318m  18m 3984 R  100  0.0  40:29.21 /usr/sbin/apache2 -k start
23523 www-data  20   0  319m  20m 4684 R  100  0.0   4:12.36 /usr/sbin/apache2 -k start

Je veux essayer de savoir quel script (ou quoi que ce soit) est à l'origine de cela, alors j'ai essayé:

 strace -p 20788

Mais cela ne montre aucune sortie (je l'ai laissé pendant environ 10 minutes, et cela ne montre rien). D'après ma compréhension, cela pourrait signifier qu'il est coincé dans une boucle infinie, et qu'il n'y a aucun "appel système" à afficher.

Puis-je faire autre chose pour montrer ce qui se passe?

Merci

Modifier - J'ai oublié de mentionner, c'est un serveur en direct avec quelques centaines d'utilisateurs à la fois! Je ne peux donc pas vraiment essayer librement de changer les options de configuration et redémarrer apache.

Edit 2 - Le backtrace (bt) de gdb ne semble pas être très utile lorsque PHP n'est pas configuré avec --enable-debug - il montre seulement "execute ()", mais j'ai besoin de savoir ce qu'est le script PHP en cours d'exécution .. existe-t-il un autre moyen?

#0  0x00007f6c143fb0c5 in ?? () from /usr/lib/apache2/modules/libphp5.so
#1  0x00007f6c143b040b in execute () from /usr/lib/apache2/modules/libphp5.so
#2  0x00007f6c1438b970 in zend_execute_scripts () from     /usr/lib/apache2/modules/libphp5.so
#3  0x00007f6c14337fe3 in php_execute_script () from     /usr/lib/apache2/modules/libphp5.so
#4  0x00007f6c1441ae7d in ?? () from /usr/lib/apache2/modules/libphp5.so
#5  0x00007f6c18912508 in ap_run_handler ()
#6  0x00007f6c1891297e in ap_invoke_handler ()
#7  0x00007f6c18922570 in ap_process_request ()
#8  0x00007f6c1891f398 in ?? ()
#9  0x00007f6c18918fa8 in ap_run_process_connection ()
#10 0x00007f6c189271d0 in ?? ()
#11 0x00007f6c1892793a in ?? ()
#12 0x00007f6c189284e7 in ap_mpm_run ()
#13 0x00007f6c188fd4a4 in main ()
BT643
la source
1
Apache prend en charge le redémarrage "gracieux", alors pourquoi pas?
poige
1
Je pense que lorsque nous l'avons essayé auparavant, il ne pouvait pas redémarrer correctement à cause des processus apache "bloqués" ... bien que cela puisse être faux, c'était il y a un certain temps.
BT643
Une autre astuce consiste à exécuter une autre instance d'apache sur un port différent, en redirigeant de nouvelles connexions vers celui-ci.
poige

Réponses:

9

Eh bien, au cas où vous vous sentiriez courageux:

gdb -p 20788

puis émettez btpour voir le cadre de la pile, par exemple

Et BTW, il y a aussi ltraceà mentionner - essayez-le également.

UPD. : bien, ok, puisque maintenant nous avons une idée qu'Apache exécute vraiment quelque chose, pourquoi ne pas regarder la mod_statussortie - Extended ?

poige
la source
gdb n'est pas installé :( devra attendre que je retourne au travail demain pour voir si je peux l'installer sans causer de problèmes .. ltracen'a montré aucune sortie non plus.
BT643
Je viens d'ajouter les résultats du gdb bt dans le post initial .. ne me dit pas grand-chose du tout!
BT643
Oh, content de voir que j'ai suggéré la bonne direction. )
poige
@ BT643, voir UPD.
poige
4
Le mod_status réalisé était déjà activé par défaut, il était juste limité à l'accès à partir de 127.0.0.1. Je viens de me connecter via SSH et j'ai canalisé la sortie vers un fichier curl domain.com/server-status > randomfile.html- puis j'ai consulté le fichier. Il s'est avéré que c'était un vieux code de développeur coincé dans une boucle (fichier PHP)! Tout est trié maintenant. Merci pour l'aide :)
BT643
2

Une approche très simple consiste à utiliser htop. Vous pouvez trier pour les processus CPU élevés, puis utiliser

  • s pour straceun processus
  • l pour lsofvoir les fichiers ouverts d'un processus
  • L à ltrace.

J'ai trouvé qu'au moins une de ces options trouve le script qui génère la charge et vous pouvez bien sûr l'utiliser sur un serveur Web de production pour déboguer.

abuzze
la source
1

Tu pourrais essayer:

  • iotop (montrant les E / S sur le système)
  • netstat -t (montrant les connexions)
  • Jetez un œil aux fichiers journaux d'apache et découvrez ce que le serveur a fait en dernier
  • définir quelques RLimits pour le processus apache. Lorsque ces limites seront atteintes, le processus sera tué, vous donnant ainsi plus d'informations
Kai Bojens
la source
0

Votre commande devrait fonctionner à condition que vous fassiez une demande HTTP qui déclenche ce PID.

Vous souhaitez peut-être reconfigurer temporairement Apache avec un seul processus enfant?

Harry Slaughter
la source
Gardez à l'esprit qu'un seul processus enfant signifie qu'Apache ne peut servir qu'une seule demande, et si cet enfant unique est bloqué, Apache ne pourra pas répondre à aucune demande.
Stefan Lasiewski
Impossible de le faire car c'est un serveur en direct avec des centaines d'utilisateurs simultanés (ont ajouté cela dans l'OP car cela n'était pas clair auparavant)
BT643
0

Le PID de cette instance d'Apache est faible, il pourrait être le père de tout le lot. Cela expliquerait certainement l'utilisation élevée du processeur (il reste, d'autres sont générés et rappelés en fonction de la charge). Une grande partie du temps CPU accumulé pourrait simplement signifier qu'il fonctionne depuis longtemps. Aucune sortie de strace(1)signifie simplement qu'il n'a fait aucun appel système. Oui, cela pourrait être dans une boucle étroite, mais apache est essentiellement des E / S sur le net, donc je pense qu'il ne fait rien d'utile. Étrange à 100% d'un CPU, en tout cas.

vonbrand
la source
Un PID faible ne signifie pas nécessairement qu'il s'agit d'un ancien processus. Les PID ont une valeur maximale et s'articulent pour que de nouveaux processus puissent être créés à l'aide de PID faibles.
austinian
0

Essaye ça:

1) Démarrez un journal avec la date / heure, le script PHP et le PID en utilisant getmypid()

2) Regardez ensuite votre serveur avec top

3) Lorsque vous voyez le processus Apache monter en puissance, recherchez la même date / heure et le même PID dans vos journaux. Vous devriez pouvoir trouver le script problématique.

phénix
la source
C'est une solution intéressante mais je peux voir qu'elle utilise plus de ressources qu'elle n'en vaut, étant donné que cela mod_statusfait très bien son travail.
austinienne