Ungefähr einmal in der Woche, aber manchmal sogar ein paar Mal am Tag, nachdem meine EC2-Instanzen tagelang fehlerfrei gelaufen sind, reagieren sie nicht mehr. Munins Speichergraphen erzählen eine recht einfache Geschichte: Der den "Apps" zugewiesene Speicher wächst und hört erst auf, wenn der Swap vollständig genutzt und die Instanz effektiv auf die Knie gesenkt wird. Ein anderes benutzerdefiniertes Diagramm zeigt, dass der ständig wachsende Prozess Apache2 ist.
Ich führe ein Standard-Prefork-Apache-Setup mit mod_php und einigen PHP-Skripten aus. Wie Sie in der folgenden Grafik sehen können, geschieht etwas, das Apache2-Prozesse dazu veranlasst, immer mehr Speicher zu verbrauchen. Die erste grüne Spitze, die ich rechtzeitig abfing und Apache neu startete, bevor die Dinge außer Kontrolle gerieten. Der zweite Spike wurde etwas weiter und die Instanz musste sofort neu gestartet werden.
Ich frage mich, wie ich das am besten debuggen kann. Was ist ein guter Weg, um herauszufinden, ob es sich um Apache oder eine Kombination aus PHP und meinem Code handelt, der die übermäßige Speichernutzung verursacht, ohne PHP mit FastCGI einzurichten und in seinen eigenen Prozessen zum Laufen zu bringen? Welche Schritte würdet ihr unternehmen, um dieses Problem aufzuspüren?
UPDATE: Ich war in der Lage, das Leck aufzuspüren, nachdem ich mich gestrafft hatte, wie Matt unten vorgeschlagen hat.
Nachdem ich einen Apache2-Prozess gefunden hatte, der allmählich und kontinuierlich im Speicher wuchs, fügte ich meinem PHP-Skript ein paar weitere error_log () -Aufrufe hinzu, die die Gesamtmenge an RSS ausdruckten, die zu verschiedenen Zeitpunkten in seiner Ausführung verwendet wurde (unter Verwendung der Ausgabe von ps). Das stellte sich jedoch als irreführend heraus - während es den Anschein hatte, dass RSS erst sprang, nachdem mein Skript ausgeführt worden war, ergab ein späteres Debuggen, dass dies in der Tat nicht der Fall war. Achtung!
Glücklicherweise haben sich all diese error_log () -Aufrufe am Ende als nützlich erwiesen. Als ich strace ( strace -p <pid> -tt -o trace.log -s 256
) startete, stellte ich fest, dass der Prozess für jede Anforderung rund 400 KB Arbeitsspeicher reservierte (suchen Sie nach dem Systemaufruf 'brk' und subtrahieren Sie den Parameter des ersten Aufrufs vom Parameter des letzten Aufrufs - einige kommen normalerweise in einem Nacheinander). Ich suchte dann nach dem letzten "Write" -Systemaufruf, der meine error_log () -Meldung enthielt, die mir mitteilte, an welcher Stelle im Skript der Speicher zugewiesen wurde. Mit ein paar strategisch platzierten Aufrufen von error_log (), um die Position genauer zu bestimmen, habe ich endlich den Schuldigen gefunden.
Der Speicher leckte, als wir curl_exec () in unserem PHP-Skript aufriefen. Ein Curl-Code im Zusammenhang mit der Verarbeitung einer SSL-Verbindung hat etwas falsch gemacht - das Leck ist verschwunden, als ich auf HTTP umgestiegen bin. Das Änderungsprotokoll von Curl verweist auf einige SSL-Speicherverluste, die in 7.19.5 behoben wurden (wir waren in 7.18.2). Daher werde ich das als Nächstes versuchen.
In der Zwischenzeit arbeite ich mit einem sehr niedrigen Wert für MaxRequestsPerChild, der Apache in einem vernünftigen Rahmen hält. Vielen Dank an alle!