Finden Sie heraus, was der Apache-Prozess mit hoher CPU-Auslastung tatsächlich bewirkt.

18

Momentan gibt es einige Probleme mit unserem Server, bei denen es gelegentlich zu Apache-Prozessen kommt, die immer wieder ausgeführt werden und 100% der CPU beanspruchen.

Wenn wir oben laufen, sehen wir Folgendes:

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

Ich möchte herausfinden, welches Skript (oder was auch immer es ist) dies verursacht, also habe ich versucht:

 strace -p 20788

Aber das zeigt überhaupt keine Ausgabe an (ich habe es für ungefähr 10 Minuten belassen und es zeigt nichts an). Nach meinem Verständnis könnte dies bedeuten, dass es in einer Endlosschleife steckt und keine "Systemaufrufe" zu sehen sind.

Kann ich noch etwas tun, um zu zeigen, was los ist?

Vielen Dank

Bearbeiten - Ich habe vergessen zu erwähnen, dass dies ein Live-Server mit ein paar hundert Benutzern ist! Daher kann ich nicht einfach frei versuchen, die Konfigurationsoptionen zu ändern und Apache neu zu starten.

Edit 2 - Das Backtrace (bt) von gdb scheint nicht allzu nützlich zu sein, wenn PHP nicht mit --enable-debug konfiguriert ist - es zeigt nur "execute ()" an, aber ich muss wissen, was PHP-Skript ist läuft eigentlich .. gibt es einen anderen weg?

#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
quelle
1
Apache unterstützt einen "ordnungsgemäßen" Neustart. Warum sollten Sie das nicht tun?
Poige
1
Ich denke, als wir es zuvor ausprobiert haben, konnte es wegen der "festgefahrenen" Apache-Prozesse nicht ordnungsgemäß neu gestartet werden ... obwohl dies möglicherweise falsch ist, ist es eine Weile her.
BT643
Ein weiterer Trick besteht darin, eine weitere Instanz von Apache auf einem anderen Port auszuführen und neue Verbindungen dorthin umzuleiten .
Poige

Antworten:

9

Nun, falls Sie sich mutig fühlen:

gdb -p 20788

dann ausgeben bt, um den Stack-Frame zu sehen, z

Und übrigens gibt es auch ltrace zu erwähnen - versuchen Sie es auch.

UPD. : nun, ok, da wir jetzt eine Idee haben, dass Apache wirklich etwas ausführt, warum würdest du nicht auf die mod_statusAusgabe schauen - Erweiterte ?

Poige
quelle
gdb ist nicht installiert :( muss warten, bis ich morgen wieder zur Arbeit gehe, um zu sehen, ob ich es ohne Probleme installieren kann .. ltracezeigte auch keine Ausgabe.
BT643
Habe gerade die Ergebnisse vom gdb bt in den ersten Post eingefügt. Erzählt mir eigentlich gar nicht viel!
BT643
Oh, froh zu sehen, dass ich die richtige Richtung vorgeschlagen habe. )
14.
@ BT643, siehe UPD.
Poige
4
Realisiert, dass mod_status bereits standardmäßig aktiviert war, war es nur auf den Zugriff von 127.0.0.1 beschränkt. Ich habe mich gerade über SSH angemeldet und die Ausgabe in eine Datei umgeleitet curl domain.com/server-status > randomfile.html- und dann die Datei angesehen. Es stellte sich heraus, dass es sich um einen alten Entwicklercode handelte, der in einer Schleife steckte (PHP-Datei)! Alles ist jetzt sortiert. Vielen Dank für die Hilfe :)
BT643
2

Ein sehr einfacher Ansatz ist die Verwendung htop. Sie können nach Prozessen mit hoher CPU-Auslastung sortieren und diese dann verwenden

  • s für straceeinen Prozess
  • l um lsofdie offenen Dateien eines Prozesses zu sehen
  • L bis ltrace.

Ich fand, dass mindestens eine dieser Optionen das Skript findet, das die Last generiert, und Sie können dies natürlich auf einem Produktions-Webserver zum Debuggen verwenden.

beschimpfen
quelle
1

Du könntest es versuchen:

  • iotop (zeigt I / O auf dem System an)
  • netstat -t (zeigt Verbindungen)
  • Schauen Sie sich die Apache-Protokolldateien an und finden Sie heraus, was der Server zuletzt getan hat
  • Legen Sie einige RLimits für den Apache-Prozess fest. Wenn diese Grenzwerte erreicht sind, wird der Vorgang abgebrochen und Sie erhalten weitere Informationen
Kai Bojens
quelle
0

Ihr Befehl sollte funktionieren, vorausgesetzt, Sie stellen eine HTTP-Anfrage, die diese PID auslöst.

Vielleicht möchten Sie Apache vorübergehend mit nur einem untergeordneten Prozess neu konfigurieren?

Harry Slaughter
quelle
Denken Sie daran, dass nur ein untergeordneter Prozess bedeutet, dass Apache nur eine einzelne Anforderung bedienen kann. Wenn dieses einzelne untergeordnete Element blockiert ist, kann Apache keine Anforderungen bedienen.
Stefan Lasiewski
Dies ist nicht möglich, da es sich um einen Live-Server mit Hunderten von gleichzeitigen Benutzern handelt (haben dies dem OP hinzugefügt, da es vorher nicht klar war)
BT643
0

Die PID dieser Apache-Instanz ist niedrig, sie ist möglicherweise der Vater der ganzen Menge. Das würde sicherlich die hohe CPU-Auslastung erklären (es bleibt bestehen, andere werden je nach Auslastung erzeugt und abgerufen). Viel akkumulierte CPU-Zeit kann bedeuten, dass es schon lange läuft. Keine Ausgabe von strace(1)bedeutet nur, dass keine Systemaufrufe ausgeführt wurden. Ja, es könnte sich um eine enge Schleife handeln, aber Apache ist im Wesentlichen I / O über das Netz, also würde ich denken, dass es nichts Sinnvolles macht. Seltsame 100% einer CPU auf jeden Fall.

vonbrand
quelle
Niedrige PID bedeutet nicht unbedingt, dass es ein alter Prozess ist. PIDs haben einen Maximalwert und werden umgangen, damit neue Prozesse mit niedrigen PIDs erstellt werden können.
Austin
0

Versuche dies:

1) Starten Sie ein Protokoll mit Datum / Uhrzeit, PHP-Skript und der PID mit getmypid()

2) Beobachten Sie dann Ihren Server mit top

3) Wenn der Apache-Prozess zu hoch wird, suchen Sie in Ihren Protokollen nach demselben Datum / derselben Uhrzeit und derselben PID. Sie sollten in der Lage sein, das problematische Skript zu finden.

Phönix
quelle
Dies ist eine interessante Lösung, aber ich kann sehen, dass sie mehr Ressourcen in Anspruch nimmt, als es wert ist, da mod_statussie ihre Aufgabe recht gut erfüllt.
Austin