PHP-FPM Einstellungen optimieren
Heute geht es darum den unter PHP Nutzern bekannten FastCGI Process Manager (FPM) richtig zu konfigurieren und zu optimieren. (https://php-fpm.org/)
Die meisten PHP Anwendungen verwenden Heutzutage den PHP-FPM um Ihre PHP Anwendungen auszuliefern. In Kombination mit NGINX als Webserver ist dies mit einer der effektivsten Methoden eine Webanwendung mit PHP im Produktiveinsatz laufen zu lassen.
Der Teufel steckt im Detail
- FPM Master Prozess startet nicht mehr
- RAM des Servers läuft voll
- „server reached max_children“
Prüfen ob PHP-FPM Prozess läuft
ps aux | grep fpm
PHP-FPM Konfiguration anpassen
nano /etc/php/7.0/fpm/pool.d/web1.conf
Der Inhalt der Datei sieht dann so aus (kann je nach Installation abweichen):
[web1] listen = /var/lib/php7.0-fpm/web1.sock listen.owner = web1 listen.group = www-data listen.mode = 0660 user = web1 group = www-data pm = dynamic pm.max_children = 50 pm.start_servers = 12 pm.min_spare_servers = 8 pm.max_spare_servers = 24 pm.max_requests = 1000 .... ....
Ich werde jetzt die wichtigsten Einstellung im Detail erklären und euch gegebenenfalls Hinweise dazu geben. Aber fangen wir direkt an mit der wohl wichtigsten Einstellung „pm.max_children“.
Wichtigste PHP-FPM Einstellungen einfach erklärt
- pm (string)
- es gibt 3 mögliche Einstellungen, dynamic ist meistens die beste Wahl
- static – Anzahl der Kindprozesse ist fest (pm.max_children)
- ondemand – Kindprozess wird erst erstellt wenn er benötigt wird (pm.start_servers)
- dynamic – dynamische Einstellung der Kindprozesse (benötigt folgenden Einstellungen: pm.max_children, pm.start_servers, pm.min_spare_servers, pm.max_spare_servers)
- pm.max_children (int)
- Anzahl der Kindprozesse die erstellt werden wenn pm = static oder die maximale Anzahl der Kindprozesse wenn pm = dynamic. Einstellung ist notwendig!
- pm.start_servers (int)
- Anzahl an Kindprozessen, die beim Start erstellt werden. Wird nur verwendet, wenn pm auf dynamic gesetzt ist. Standardwert: min_spare_servers + (max_spare_servers – min_spare_servers) / 2.
- pm.min_spare_servers (int)
- gewünschte Mindestanzahl an Prozessen. Wird nur genutzt, wenn pm auf dynamic gesetzt ist. Zwingend notwendig!
- pm.max_spare_servers (int)
- gewünschte Maximalanzahl an Prozessen. Wird nur genutzt, wenn pm auf dynamic gesetzt ist. Zwingend notwendig!
- pm.max_requests (int)
- Anzahl der Requests bis der FPM Prozess neustartet, hilft Memory Leaks in einigen PHP Libs zu fixen
Optimalen Wert für „pm.max_children“ bestimmen
ps -ylC php-fpm7.0 --sort:rss
Für uns von Bedeutung ist die Spalte „RSS“ diese gibt den Speicherverbrauch des Prozesses in Kilobyte an. Also wären 43868 rund ~ 43MB für diesen Prozess. Um das ganze etwas zu vereinfachen können wir aber einfach den Befehl ausführen und erhalten den Durchschnitt.
ps --no-headers -o "rss,cmd" -C php-fpm7.0 | awk '{ sum+=$1 } END { printf ("%d%sn", sum/NR/1024,"Mb") }' // Output 34Mb
Mit diesem Verbrauchswert können wir nun den passenden Wert für pm.max_children berechnen. Dazu nehme ich einfach mal ein Beispiel (einen VPS der 2GB RAM hat).
- VPS mit 2 GB RAM
- wir ziehen 256 MB ab da noch andere Dienste auf dem VPS laufen
- uns bleiben 1792 MB Ram
- Formel: max_children = Free RAM VPS / RAM pro Prozess
- max_children = 1792 / 34
- = 52,7 = ~ 52
sudo /etc/init.d/php7.0-fpm restart