Nginx + php-fpm - Jeder php-fpm verarbeitet 70-100% CPU beim Ausführen

8

Ich habe eine Situation, in der Folgendes stattfindet:

  • Wir sind auf Linode mit 8-Core, 8 GB RAM, 2,6 GHz - mit Nginx + PHP-Fpm - wir bekommen extrem hohe Diagramme der CPU-Auslastung (die wir nicht so ein schlechter VPS-Nachbar sein wollen) ...

  • Wir haben jeweils weniger als 100 Benutzer auf der Website - daher ist diese Situation auch unglaublich peinlich -, dass unsere CPU-Auslastung sehr hoch ist.

  • Wir verwenden ein sehr unbekanntes, möglicherweise CPU-intensives PHP-weises, fragwürdig schreckliches Framework anstelle von bekannten, gut dokumentierten, gut gestalteten anderen Frameworks wie WordPress oder Drupal, in denen es VIELE Dokumentation zum Caching (sowie Plugins) gibt die Caching behandeln) PHP auf einer Nginx + Php_Fpm-Plattform.

  • Wir haben also ungefähr 6 offene PHP-Fpm-Prozesse, die beim LAUFEN individuell GROSSE (30+ und oft fast 99%) Mengen an CPU verbrauchen - und ich habe nicht die geringste Ahnung, wie ich sie davon abhalten kann, so viel CPU zu verwenden . Ich kann nicht sagen, welche PHP-Skripte diese Spitzen verursachen, weil sie ständig auftreten ... normalerweise werden nur 1 oder 2 ausgeführt - aber wenn alle 6 ausgeführt werden, maximieren wir alle 8 CPUs.

  • Meine Datei pool.d / www.conf hat die folgenden Einstellungen:

    pm = dynamic
    pm.max_children = 10
    pm.start_servers = 4
    pm.min_spare_servers = 2
    pm.max_spare_servers = 6
    
  • Wir haben dieses Setup durchgeführt, weil unser Speicher in der Art und Weise, wie ich es interpretiere, tatsächlich erstaunlich ist (htop zeigt 472/7000 + mb verwendet, kein Tauschen usw.) und wir könnten viel mehr Prozesse handhaben und die Warteschlange abbrechen, die darauf wartet, sie zu bekommen verarbeitet - ABER leider, da jeder Prozess auf unserer CPU beim Ausführen zu intensiv ist, treiben wir am Ende unsere CPU durch das Dach - so dass wir nicht genug Prozesse verarbeiten können.

  • Die Frage - was um alles in der Welt können wir tun, um die CPU-Auslastung des Prozesses php-fpm zu reduzieren, damit wir die Einstellungen in dieser Pool-Conf-Datei für php-fpm erhöhen können - und auch ja, die Datei /var/log/php5-fpm.log schreit uns an, unsere Kinder zu vergrößern und unsere Min / Max / Start-Server anzupassen / zu erhöhen. Aber das macht unseren Lastdurchschnitt verrückt, wie bereits erwähnt. Wie können wir dies tun, ohne unbedingt einen Cache zu verwenden, oder welche Optionen haben wir?

  • Meine Idee? Ich habe Dinge über die Verwendung von cpulimit gelesen, um sicherzustellen, dass kein Prozess mehr als eine zugewiesene Menge an CPU benötigt - aber wird dies die Dinge verlangsamen, um unbrauchbar zu werden? Auf diese Weise könnten wir unsere Fähigkeit verbessern, mehr als ein paar Prozesse auszuführen - ich dachte auch, zwei Pools auszuführen - einen für unsere nach vorne gerichtete Website (was Kunden erleben) und einen für ein Backend (was sich auf unsere nach vorne gerichtete Website auswirkt, wenn es Zeit ist) -Verbrauchende Berichte werden ausgeführt).

  • Ich habe ein paar Tage damit verbracht, zu diesem Thema zu recherchieren, zu googeln usw. - und es ist schwierig, weil die Situation eines jeden so einzigartig für sein System ist - das Problem liegt in einem so spezifischen, unerhörten, möglicherweise schlecht geschriebenen Rahmen es ist schwer, eine Lösung zu finden. Wir können dieses Framework auch noch nicht einfach ausrangieren - ich muss eine Lösung finden.


UPDATE: Ich habe Memcache implementiert, um PHP-Sitzungen zu speichern. Da das Framework stark von Benutzersitzungen abhängt und die Art unseres Systems darin besteht, dass Mitarbeiter häufig mehrere Registerkarten gleichzeitig verwenden, wird jeweils auf die Sitzungen zurückgegriffen, um die Fähigkeiten / Benutzerdaten / etc. Zu bestätigen ... also hoffe ich auf eine gewisse Leistungssteigerung - bitte kommentieren Sie dies, wenn Sie möchten - ich werde sehen, wie es morgen läuft, wenn wir unsere Spitzenzeiten mit höherem Volumen überstehen.

amurrell
quelle
Nginx ist nicht sehr gut für eine CPU-intensive Webanwendung - aber unsere hohe CPU ist schlecht - wirklich schlecht - und wir arbeiten daran, dies zu beheben. Es gibt kein großartiges Max-Client-Setup, da es eine anständige Anzahl von Clients unterstützen sollte - aber die hohe CPU-Auslastung pro Prozess verzerrt diese Fähigkeit. Wir sind nur deshalb auf Apache umgestiegen, weil es bei hoher CPU-Auslastung ein KLEINES besser macht - aber letztendlich weist dieses Problem eher auf ein Web-App-Problem hin, und es kann eine Weile dauern, bis es behoben ist, aber es gibt keine Zeit wie die Gegenwart, um mit der Behebung zu beginnen.
Amurrell
Wenn Sie zum Arzt gehen und er Ihnen sagt, dass Sie bestimmte Medikamente einnehmen sollen - weil er weiß, dass Sie nicht auf die Aussagen "aufhören, Soda zu trinken und Fastfood zu essen" hören -, gab es genau deshalb keine gute Antwort für mich - denn die Wahrheit ist , kein Setup oder schnelle Lösung wirklich angewendet - nur die traurige Wahrheit, dass wir unsere Web-App selbst dramatisch ändern müssen.
Amurrell
Glücklicherweise haben Sie, wenn Sie dieses Problem mit einem beliebten Framework haben, möglicherweise die Möglichkeit, das Caching und die umfangreiche Dokumentation zu nutzen - aber wir haben eine obskure zufällige Sache, die wir nur mit dem Framework selbst ändern können. Yay!
Amurrell
1
Soweit ich weiß, speichert opcache Ihren PHP-Code als binär und kann von php-fpm viel schneller verwendet werden (Caching). Sie sollten jedoch auch das Objekt-Caching verwenden. Ein Beispiel ist das Speichern einer gesamten Seitenausgabe als "Objekt" "in so etwas wie memcached. Dies würde tatsächlich die Seitenausgabe zwischenspeichern (oder andere Dinge, die Sie wollen, wie die PHP-Sitzungen usw.) ... Als nächstes könnten Sie auch Lack verwenden, der ein Reverse-Proxy ist - aber im Grunde ist es ein Mittler zwischen der Anfrage und Ihrem Server, so dass Ihre Der Server wird nicht direkt von Anforderungen betroffen - und er arbeitet aus dem Speicher, um die zwischengespeicherten URLs bereitzustellen.
Amurrell
1
Der Lack ist dafür fantastisch - er speichert eine zwischengespeicherte Kopie dessen, was er vom Server im Speicher erhalten hat -, sodass der Lack einen Großteil der Last beansprucht. Mein aktueller Arbeitgeber ist bei Nginx und wir verwenden Lack und Memcached. Glücklicherweise verfügt das Framework, auf dem wir uns gerade befinden, über einen eigenen Caching-Mechanismus, um den Seiten-Cache (ausgegebene Seitendaten) zu bestimmen. Bei meinem letzten Job musste ich es selbst in das Framework schreiben - es hat keinen Spaß gemacht, aber es hat funktioniert. Apache - Ich würde nicht zurückwechseln, es sei denn, Sie haben keine Zeit, Nginx zu reparieren. Ich hasste es, zurück zu gehen, aber es war das einzige Lösung, um unser Projekt nicht vollständig zu beenden, während ich den Caching-Mechanismus schrieb.
Amurrell

Antworten:

6

Ein paar Dinge zu beachten (Entschuldigung im Voraus, wenn Sie diese bereits berücksichtigt haben): Stellen Sie zunächst sicher, dass Sie Ihre Nginx-Konfiguration optimieren und php-fpm nur dann aufrufen, wenn dies unbedingt erforderlich ist. Das Letzte, was Sie tun möchten, ist, PHP Dinge wie statische HTML-Seiten behandeln zu lassen (was es gerne tun wird).

Zweitens, da Sie php-fpm verwenden, schlage ich vor, aggressiver damit umzugehen, wie lange die Kinder von php-fpm leben dürfen. Sie müssen den Sweet Spot zwischen kurzlebigen Fäden / Kindern und Stabilität finden. Die PHP-Fpm-Standardeinstellungen sind meiner Meinung nach für jedes Produktionssystem viel zu großzügig. Je länger ein Mitarbeiter Anfragen bearbeiten darf, desto instabiler wird er. Es besteht auch ein höheres Risiko für Speicherlecks. Wenn dieses Framework, auf das Sie sich beziehen, Fehler wie Endlosschleifen aufweist, die Sie möglicherweise über die CPU-Auslastung beunruhigen, sollte dies nicht schaden.

Ich würde die Anzahl pm.max_requestsfür Ihre Produktionspools reduzieren . Ich denke, der Standardwert ist 200. Ich würde bei 50 anfangen und sehen, wohin Sie das führt.

Andernfalls können Sie auch diese globalen Optionen ausprobieren (AFAIK, alle sind standardmäßig deaktiviert):

emergency_restart_threshold 3
emergency_restart_interval 1m
process_control_timeout 5s

Was bedeutet das? Wenn 3 untergeordnete PHP-FPM-Prozesse innerhalb von 1 Minute mit SIGSEGV oder SIGBUS (dh Absturz) beendet werden, soll PHP-FPM automatisch neu gestartet werden. Der untergeordnete Prozess wartet 5 Sekunden auf eine Reaktion auf Signale vom Master.

Hier ist eine schöne Übersicht aller hier erwähnten Konfigurationsoptionen sowie anderer: http://myjeeva.com/php-fpm-configuration-101.html

Hoffe diese Tipps helfen dir! Denken Sie daran, zu optimieren und zu beobachten. Leider scheint es für all dies keine Faustregel zu geben. Wie Sie festgestellt haben, gibt es zu viele Variablen, die das Verhalten und die Stabilität von PHP beeinflussen.

Schließlich ist die CPU-Begrenzungsfunktion, nach der Sie gefragt haben , hier dokumentiert , aber ich würde nur dann darauf zurückgreifen, wenn Sie alle anderen Optionen ausschöpfen. Wenn Sie diesen Pfad wählen, würde ich auf jeden Fall auf mögliche Wechselwirkungen zwischen PHP-FPM-Optimierungen und Ihrer Limits.conf-Konfiguration achten. An diesem Punkt etckeeper kann ein Lebensretter sein! :) :)

Viel Glück!

Rouben

Rouben
quelle
Ich werde versuchen, die max_requests morgen zu begrenzen. Es scheint, als ob jeder Prozess, den wir zulassen, die CPU auffressen möchte, daher könnte dies eine gute Idee sein. Wir verwenden die Schwellenwerte für den Notfall-Neustart, aber meine Zahlen waren etwas höher - ich werde Ihre ausprobieren und sehen, wie die Dinge laufen. Vielen Dank für Ihre Gründlichkeit - sehr geschätzt. Wollten Sie Ihre Gedanken zum Caching wissen? Ich frage mich, ob die Verwendung von PHP-Caching bedeutet, dass das Framework angepasst werden müsste, um damit umzugehen. Ich bin ziemlich neu in diesem Konzept.
Amurrell
3

Sie führen Opcode-Caching aus, richtig?

Früher war es APC, das hier die erste Wahl war , aber es war schon eine ganze Weile ein Buggy-Teil und wurde von Zend Opcache abgelöst , das jetzt seit 5.5 Teil von PHP ist und einen Backport in PECL für 5.3 hat und 5.4.

Michael Hampton
quelle
Ich interessiere mich für diesen Zend OpCache - Wir sind auf 5.3 - Wenn Sie diese Antwort erweitern könnten, würde ich es wirklich schätzen!
Amurrell
Wir hatten xcache - aber jetzt habe ich mich für Zend Opcache entschieden und es installiert und bestätigt, dass es in phpinfo () läuft. Ich werde Sie wissen lassen, ob unsere Leistung besser ist, da die Daumen
drücken
Ich musste vorerst den Zend-Opcache deaktivieren - alles funktionierte außer allen von Dynamic PHP generierten CSS- oder JS-Dateien. Ich habe versucht, diese Dateien aus dem Opcache auf die schwarze Liste zu setzen - aber entweder hat die schwarze Liste nicht funktioniert oder ich kann nicht sagen, warum der Opcache dazu führt, dass nginx 502 fehlerhafte Gateway-Fehler für NUR diese Dateien erhält. Was ich für die Vorlage brauche und sie sind Teil des schlechten Frameworks. In den Nginx-Protokollen erhielt ich Tonnen von Readv fehlgeschlagen - 104 Peer-Verbindungsfehler.
Amurrell