Geekflare wird von unserem Publikum unterstützt. Es kann sein, dass wir durch den Kauf von Links auf dieser Seite Affiliate-Provisionen verdienen.
Unter Entwicklung Zuletzt aktualisiert: September 24, 2023
Weitergeben:
Invicti Web Application Security Scanner - die einzige Lösung, die eine automatische Überprüfung von Schwachstellen mit Proof-Based Scanning™ ermöglicht.

PHP ist allgegenwärtig und ist wohl die Sprache, die am häufigsten im Internet eingesetzt wird.

Allerdings ist sie nicht gerade für ihre Hochleistungsfähigkeiten bekannt, insbesondere wenn es um hochgradig nebenläufige Systeme geht. Und das ist der Grund, warum Sprachen wie Node (ja, ich weiß, es ist keine Sprache), Weiter und Elixier für solche speziellen Anwendungsfälle immer mehr an Bedeutung gewinnen

Dennoch gibt es eine Menge, was Sie tun können, um die PHP-Leistung auf Ihrem Server zu verbessern. Dieser Artikel konzentriert sich auf die php-fpm Seite, die Sie natürlich auf Ihrem Server konfigurieren müssen, wenn Sie Nginx verwenden

Falls Sie wissen, was php-fpm ist, können Sie gerne zu dem Abschnitt über die Optimierung springen

Was ist PHP-fpm?

Nicht viele Entwickler interessieren sich für die DevOps-Seite der Dinge, und selbst von denen, die sich dafür interessieren, wissen nur wenige, was unter der Haube vor sich geht. Interessanterweise ist es nicht PHP, das den ersten Kontakt herstellt, wenn der Browser eine Anfrage an einen Server sendet, auf dem PHP läuft, sondern der HTTP-Server, von denen die wichtigsten Apache und Nginx sind. Diese "Webserver" müssen dann entscheiden, wie sie sich mit PHP verbinden und den Anfragetyp, die Daten und die Kopfzeilen an PHP weiterleiten.

request-response-in-php-e1542398057451
Der Anfrage-Antwort-Zyklus im Falle von PHP (Bildnachweis: ProinerTech)

In modernen PHP-Anwendungen ist der obige Teil "Datei finden" die index.php, die der Server so konfiguriert hat, dass alle Anfragen an sie weitergeleitet werden

Wie der Webserver die Verbindung zu PHP herstellt, hat sich weiterentwickelt, und dieser Artikel würde in seiner Länge explodieren, wenn wir auf alle Einzelheiten eingehen würden. Aber grob gesagt war PHP in der Zeit, in der Apache der Webserver der Wahl war, ein in den Server integriertes Modul

Wenn also eine Anfrage eintraf, startete der Server einen neuen Prozess, der automatisch PHP einschloss und es ausführen ließ. Diese Methode wurde mod_php genannt, kurz für "PHP as a module" Dieser Ansatz hatte seine Grenzen, die Nginx mit php-fpm hat überwunden

Bei php-fpm liegt die Verantwortung für die Verwaltung der PHP-Prozesse bei dem PHP-Programm auf dem Server. Mit anderen Worten, dem Webserver (in unserem Fall Nginx) ist es egal, wo sich PHP befindet und wie es geladen wird, solange er weiß, wie er Daten senden und von ihm empfangen kann. Wenn Sie möchten, können Sie sich PHP in diesem Fall als einen weiteren Server vorstellen, der einige untergeordnete PHP-Prozesse für eingehende Anfragen verwaltet (die Anfrage erreicht auch einen Server, wird von einem Server empfangen und an einen Server weitergeleitet - ziemlich verrückt! :-P)

Wenn Sie schon einmal Nginx eingerichtet haben oder auch nur ein wenig darin herumgestöbert haben, werden Sie auf etwas wie dieses stoßen

    Standort ~ .php$ {
 try_files $uri =404;
 fastcgi_split_path_info ^(. .php)(/. )$;
 fastcgi_pass unix:/run/php/php7.2-fpm.sock;
 fastcgi_index index.php;
 include fastcgi_params;
 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
 }

Die Zeile, die uns interessiert, ist diese: fastcgi_pass unix:/run/php/php7.2-fpm.sock;, die Nginx anweist, mit dem PHP-Prozess über den Socket namens php7.2-fpm.sock zu kommunizieren. Bei jeder eingehenden Anfrage schreibt Nginx auch Daten in diese Datei und sendet sie nach Erhalt der Ausgabe zurück an den Browser

Ich muss noch einmal betonen, dass dies nicht das vollständigste oder genaueste Bild der Vorgänge ist, aber für die meisten DevOps-Aufgaben ist es völlig ausreichend

Lassen Sie uns nun rekapitulieren, was wir bisher gelernt haben

  • PHP empfängt die von den Browsern gesendeten Anfragen nicht direkt. Webserver wie Nginx fangen diese zunächst ab.
  • Der Webserver weiß, wie er sich mit dem PHP-Prozess verbinden kann, und gibt alle Anfragedaten an PHP weiter (er fügt buchstäblich alles ein).
  • Wenn PHP mit seiner Arbeit fertig ist, sendet es die Antwort an den Webserver zurück, der sie wiederum an den Client (oder Browser, in den meisten Fällen) weiterleitet.

Oder grafisch dargestellt

php-und-nginx
Wie PHP und Nginx zusammenarbeiten (Bildnachweis: DataDog)

Soweit so gut, aber jetzt kommt die Millionen-Dollar-Frage: Was genau ist PHP-FPM?

Das "FPM" in PHP steht für "Fast Process Manager", was nichts anderes bedeutet, als dass das auf einem Server laufende PHP kein einzelner Prozess ist, sondern mehrere PHP-Prozesse, die von diesem FPM-Prozessmanager gestartet, gesteuert und beendet werden. Es ist dieser Prozessmanager, der an den Webserver die Anfragen weiterleitet

Der PHP-FPM ist ein ganzes Kaninchenloch für sich, also erforschen Sie ihn ruhig, wenn Sie möchten, aber für unsere Zwecke reicht diese kurze Erklärung 🙂

Warum PHP-fpm optimieren?

Warum sollten Sie sich auch um all diese Dinge kümmern, wenn alles gut funktioniert? Warum lassen Sie die Dinge nicht einfach so, wie sie sind

Ironischerweise ist das genau der Rat, den ich für die meisten Anwendungsfälle gebe. Wenn Ihr System einwandfrei funktioniert und es keine außergewöhnlichen Anwendungsfälle gibt, sollten Sie die Standardeinstellungen verwenden. Wenn Sie jedoch über einen einzelnen Rechner hinaus skalieren wollen, dann ist es wichtig, das Maximum aus einem Rechner herauszuholen, da dieser die Serverkosten um die Hälfte (oder sogar mehr!) reduzieren kann.

Ein weiterer wichtiger Punkt ist, dass Nginx für die Bewältigung großer Arbeitslasten entwickelt wurde. Es ist in der Lage, Tausende von Verbindungen gleichzeitig zu verarbeiten, aber wenn das nicht auch auf Ihre PHP-Einrichtung zutrifft, verschwenden Sie nur Ressourcen, da Nginx darauf warten muss, dass PHP den aktuellen Prozess beendet und den nächsten annimmt, was die Vorteile, für die Nginx entwickelt wurde, endgültig zunichte macht!

Nachdem das geklärt ist, wollen wir uns nun ansehen, was genau wir ändern, wenn wir es versuchen, php-fpm zu optimieren

Wie optimiert man PHP-FPM?

Der Speicherort der Konfigurationsdatei für php-fpm kann je nach Server unterschiedlich sein, so dass Sie etwas suchen müssen. Unter UNIX können Sie den Befehl finden verwenden. Auf meinem Ubuntu lautet der Pfad /etc/php/7.2/fpm/php-fpm.conf. Die 7.2 ist natürlich die Version von PHP, die ich verwende.

Die ersten Zeilen dieser Datei sehen folgendermaßen aus

;;;;;;;;;;;;;;;;;;;;;
FPM-Konfiguration ;
;;;;;;;;;;;;;;;;;;;;;

Alle relativen Pfade in dieser Konfigurationsdatei sind relativ zum Präfix der PHP-Installation
; (/usr). Dieser Präfix kann dynamisch mit dem
; '-p' Argument von der Kommandozeile aus geändert werden.

;;;;;;;;;;;;;;;;;;
; Globale Optionen ;
;;;;;;;;;;;;;;;;;;

[global]
; Pid-Datei
Hinweis: der Standardpräfix ist /var
; Standardwert: keiner
pid = /run/php/php7.2-fpm.pid

; Fehlerprotokolldatei
Wenn sie auf "syslog" gesetzt ist, wird das Protokoll an syslogd gesendet, anstatt
; in eine lokale Datei geschrieben zu werden.

; Hinweis: Der

 Standardpräfix ist /var
Standardwert: log/php-fpm.log
error_log = /var/log/php7.2-fpm.log

Ein paar Dinge sollten sofort auffallen: Die Zeile pid = /run/php/php7.2-fpm.pid sagt uns, welche Datei die Prozess-ID des php-fpm-Prozesses enthält

Wir sehen auch, dass /var/log/php7.2-fpm.log der Ort ist, an dem php-fpm seine Protokolle speichern wird

Fügen Sie in dieser Datei drei weitere Variablen wie folgt hinzu

notfall_neustart_schwelle 10
notfall_neustart_intervall 1m
prozess_steuerung_zeitüberschreitung 10s

Die ersten beiden Einstellungen dienen der Vorsicht und teilen dem php-fpm Prozess mit, dass der Hauptprozess von php-fpm neu gestartet werden soll, wenn zehn Kindprozesse innerhalb einer Minute ausfallen

Das mag sich nicht sehr robust anhören, aber PHP ist ein kurzlebiger Prozess, der viel Speicher verbraucht, so dass ein Neustart des Hauptprozesses bei einer hohen Fehlerquote viele Probleme lösen kann.

Die dritte Option, process_control_timeout, weist die Kindprozesse an, so lange zu warten, bevor sie das vom Elternprozess empfangene Signal ausführen. Dies ist in Fällen nützlich, in denen die Kindprozesse gerade etwas tun, wenn der Elternprozess z.B. ein KILL-Signal sendet. Wenn sie zehn Sekunden Zeit haben, haben sie eine bessere Chance, ihre Aufgaben zu beenden und sich ordnungsgemäß zu verabschieden.

Überraschenderweise ist dies nicht der Kern der php-fpm Konfiguration! Das liegt daran, dass php-fpm für die Bearbeitung von Webanfragen einen neuen Pool von Prozessen erstellt, für den eine eigene Konfiguration gilt. In meinem Fall war der Name des Pools www und die Datei, die ich bearbeiten wollte, war /etc/php/7.2/fpm/pool.d/www.conf

Lassen Sie uns sehen, wie diese Datei beginnt

; Starten Sie einen neuen Pool mit dem Namen 'www'.
Die Variable $pool kann in jeder Direktive verwendet werden und wird durch den
; Poolnamen ('www' hier) ersetzt
[www]

; Pro Pool-Präfix
Es gilt nur für die folgenden Direktiven:
; - 'access.log'
; - 'slowlog'
; - 'listen' (unixsocket)
; - 'chroot'
; - 'chdir'
; - 'php_values'
; - 'php_admin_values'
; Wenn nicht gesetzt, gilt stattdessen das globale Präfix (oder /usr).
Hinweis: Diese Direktive kann auch relativ zum globalen Präfix sein.
Standardwert: keiner
Präfix = /pfad/zu/pools/$pool

; Unix-Benutzer/Prozessgruppe
; Hinweis: Der Benutzer ist obligatorisch. Wenn die Gruppe nicht angegeben wird, wird die Gruppe des Standardbenutzers
; verwendet.
benutzer = www-daten
Gruppe = www-data

Ein kurzer Blick auf das Ende des obigen Schnipsels löst das Rätsel, warum der Serverprozess als www-data läuft. Wenn Sie bei der Einrichtung Ihrer Website Probleme mit den Dateiberechtigungen hatten, haben Sie wahrscheinlich den Eigentümer oder die Gruppe des Verzeichnisses auf www-data geändert, so dass der PHP-Prozess in der Lage ist, in Protokolldateien zu schreiben und Dokumente hochzuladen, usw.

Schließlich kommen wir zum Kern des Problems, der Einstellung des Prozessmanagers (pm). In dieser Regel sehen die Standardeinstellungen etwa so aus

pm = dynamisch
pm.max_children = 5
pm.start_server = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 4
pm.max_requests = 200

Was bedeutet auch"dynamisch" hier? Ich denke, die offiziellen Dokumente erklären dies am besten (ich meine, dies sollte bereits Teil der Datei sein, die Sie bearbeiten, aber ich habe es hier nur für den Fall wiedergegeben, dass dies nicht der Fall ist).

 Mögliche Werte:
; statisch - eine feste Anzahl (pm.max_children) von Kindprozessen;
; dynamisch - die Anzahl der Kindprozesse wird dynamisch anhand der
; folgenden Direktiven festgelegt. Bei dieser Prozessverwaltung gibt es
; immer mindestens 1 Kindprozess.
pm.max_children - die maximale Anzahl von Kindprozessen, die ; gleichzeitig aktiv sein können.
; gleichzeitig aktiv sein können.
pm.start_servers - die Anzahl der Kindprozesse, die beim Start erzeugt werden.
pm.min_spare_servers - die minimale Anzahl von Kindprozessen im 'Idle'-Zustand
; (die auf eine Verarbeitung warten). Wenn die Anzahl
; der 'Idle'-Prozesse geringer ist als diese
; Zahl, werden einige Kinder erstellt.
pm.max_spare_servers - die maximale Anzahl von Kindern im 'Idle'-Zustand
; (die auf die Verarbeitung warten). Wenn die Anzahl
; der 'Idle'-Prozesse größer als diese
; Zahl ist, werden einige Kinder getötet.
; ondemand - beim Start werden keine Kinder erstellt. Kinder werden geforkt, wenn
; neue Anfragen eingehen. Die folgenden Parameter werden verwendet:
; pm.max_children - die maximale Anzahl der Kinder, die
; gleichzeitig aktiv sein können.
pm.process_idle_timeout - Die Anzahl der Sekunden, nach denen
; ein inaktiver Prozess beendet wird.
; Hinweis: Dieser Wert ist obligatorisch

Wir sehen auch, dass es drei mögliche Werte gibt

  • Statisch: Eine feste Anzahl von PHP-Prozessen wird beibehalten, egal was passiert.
  • Dynamisch: Sie können die minimale und maximale Anzahl von Prozessen angeben, die php-fpm zu einem bestimmten Zeitpunkt aufrechterhalten werden soll.
  • auf Anfrage: Prozesse werden auf Abruf erstellt und zerstört.

Welche Bedeutung haben diese Einstellungen auch?

Einfach ausgedrückt: Wenn Sie eine Website mit geringem Datenverkehr haben, ist die Einstellung "dynamisch" in den meisten Fällen eine Verschwendung von Ressourcen. Angenommen, Sie haben pm.min_spare_servers auf 3 eingestellt, dann werden drei PHP-Prozesse erstellt und aufrechterhalten, auch wenn auf der Website kein Datenverkehr herrscht. In solchen Fällen ist "ondemand" die bessere Option, die das System entscheiden lässt, wann neue Prozesse gestartet werden sollen

Andererseits werden Websites, die ein hohes Verkehrsaufkommen haben oder schnell reagieren müssen, in dieser Einstellung bestraft. Einen neuen PHP-Prozess zu erstellen, ihn in einen Pool einzubinden und ihn zu überwachen, ist ein zusätzlicher Aufwand, den Sie besser vermeiden sollten

Die Verwendung von pm = static legt die Anzahl der Kindprozesse fest, so dass die maximalen Systemressourcen für die Bedienung der Anfragen und nicht für die Verwaltung von PHP verwendet werden können. Wenn Sie sich für diesen Weg entscheiden, sollten Sie beachten, dass er seine Richtlinien und Fallstricke hat. Einen recht ausführlichen, aber sehr nützlichen Artikel dazu finden Sie hier

Abschließende Worte

Da Artikel über Web-Performance Kriege entfachen oder zur Verwirrung beitragen können, halte ich ein paar Worte für angebracht, bevor wir diesen Artikel abschließen. Beim Performance-Tuning geht es ebenso sehr um Vermutungen und dunkle Künste wie um Systemwissen

Selbst wenn Sie alle php-fpm-Einstellungen auswendig kennen, ist der Erfolg nicht garantiert. Wenn Sie keine Ahnung von der Existenz von php-fpm haben, brauchen Sie keine Zeit damit zu verschwenden, sich darüber Gedanken zu machen. Machen Sie einfach weiter mit dem, was Sie bereits tun, und machen Sie weiter

Vermeiden Sie gleichzeitig, ein Performance-Junkie zu werden. Ja, Sie können eine noch bessere Leistung erzielen, indem Sie PHP von Grund auf neu kompilieren und alle Module entfernen, die Sie nicht verwenden werden, aber dieser Ansatz ist in Produktionsumgebungen nicht vernünftig genug. Die ganze Idee der Optimierung besteht darin, zu prüfen, ob Ihre Bedürfnisse von den Standardeinstellungen abweichen (was selten der Fall ist!), und bei Bedarf kleinere Änderungen vorzunehmen

Wenn Sie nicht bereit sind, Zeit in die Optimierung Ihres PHP-Servers zu investieren, sollten Sie eine zuverlässige Plattform wie Kinsta nutzen, die sich um die Leistungsoptimierung und Sicherheit kümmert.

  • Ankush
    Autor
    Ich schreibe über, um und für das Ökosystem der Entwickler. Empfehlungen, Anleitungen, technische Diskussionen - was auch immer ich veröffentliche, ich versuche mein Bestes, um Verwirrung und Fluff zu vermeiden und umsetzbare Antworten auf der Grundlage persönlicher Erfahrungen zu geben... mehr lesen
Dank an unsere Sponsoren
Weitere gute Lektüre zum Thema Entwicklung
Energie für Ihr Unternehmen
Einige der Tools und Dienste, die Ihr Unternehmen beim Wachstum unterstützen.
  • Invicti nutzt das Proof-Based Scanning™, um die identifizierten Schwachstellen automatisch zu überprüfen und innerhalb weniger Stunden verwertbare Ergebnisse zu erzielen.
    Versuchen Sie Invicti
  • Web Scraping, Residential Proxy, Proxy Manager, Web Unlocker, Search Engine Crawler und alles, was Sie zum Sammeln von Webdaten benötigen.
    Versuchen Sie Brightdata
  • Monday.com ist ein All-in-One-Betriebssystem, mit dem Sie Projekte, Aufgaben, Arbeit, Vertrieb, CRM, Arbeitsabläufe und vieles mehr verwalten können.
    Versuch Montag
  • Intruder ist ein Online-Schwachstellen-Scanner, der Schwachstellen in Ihrer Infrastruktur aufspürt, um kostspielige Datenschutzverletzungen zu vermeiden.
    Versuchen Sie Intruder