PHP7 OPcache auf Shared-Hosting Umgebungen

  • Hallo Leute,


    ich bin aktuell dabei, eine Shared-Hosting Umgebung mit OPcache zu bereichern - jedoch stoße ich dabei auf ein paar Probleme.


    Setup:

    - KVM

    - NGINX

    - Jede Webseite hat einen eigenen User

    - Jede Webseite hat Ihren eigenen PHP-FPM Pool


    Der OPcache liegt ja im RAM und wird mit allen FPM-Prozessen geteilt. Sprich, Benutzer A könnte Dateien von Benutzer B mit der Funktion "opcache_get_status" abrufen.

    Diese Funktion könnte man zwar deaktivieren, allerdings kann ich persönlich so nicht ausschließen, dass man auch nicht über andere Umwege an die Daten kommt (durch z.B. andere Funktionen).


    Eigentlich gibt es da auch eine tolle Lösung für - "opcache.file_cache" und "opcache.file_cache_only"


    Sprich, der Shared OPcache im RAM wird deaktiviert und alles wird auf der Festplatte gespeichert.


    Jeder PHP-POOL hat folgende Settings:

    php_admin_value[opcache.enable] = 1

    php_admin_value[opcache.enable_cli] = 0

    php_admin_value[opcache.memory_consumption] = 256

    php_admin_value[opcache.max_accelerated_files] = 32531

    php_admin_value[opcache.validate_timestamps] = 1

    php_admin_value[opcache.revalidate_freq] = 0

    php_admin_value[opcache.file_cache] = /home/websitea/html/opcache

    php_admin_value[opcache.file_cache_only] = 1

    php_admin_value[opcache.validate_permission] = 1


    Ergebnis:

    Der OPcache über den RAM ist deaktiviert. Alle Daten werden in den jeweiligen Verzeichnissen der einzelnen Webseiten gespeichert. Über opcache_get_status kann man auch keine anderen Daten sehen - es gibt ja keinen "Shared OPcache" mehr.


    Bis dahin erstmal alles schick.



    Problem:

    In den Logs bemerkte ich sporadisch SEGFAULTS, welche sich auf PHP-FPM, genauer gesagt, dem OPcache bezogen haben. Zum testen hatte ich den OPcache immer deaktiviert -> dann funktionierte auch wieder alles. Nach dem erneuten aktivieren traten die Probleme nach einiger Zeit aber wieder auf.

    Dann hatte ich die Ordnergröße der einzelnen Webseiten vom OPcache via SSH geprüft -> ca. 30-60MB pro Webseite -> sprich die 256MB, welche ja eigentlich pro PHP-POOL gelten, reichen.


    Dann hatte ich das Ganze mal über opcache_get_status geprüft und siehe da, der Speicher wird über die Webseite als komplett voll angezeigt.


    Es sieht wohl so aus, als wenn die Daten zwar separat gespeichert werden aber vom System her sie trotzdem irgendwie zusammengefasst werden. Selbst ein manuelles Löschen über die Webseite mittels opcache_clear leerte die Anzeige nicht. Es wird quasi der genutzte Verbrauch der anderen Webseiten mit hinzugerechnet.


    An diesem Punkt komme ich nicht weiter...


    Betreibe jemand vom euch den OPcache "sicher" in einer Shared-Hosting Umgebung? Falls ja, wie habt ihr es gelöst?


    Vielleicht würde es ja wirklich reichen, die Funktion opcache_get_status zu deaktivieren und dann alles über den RAM laufen zu lassen (dann aber einfach über die php.ini eingestellt mit z.B. 4GB opcache.memory_consumption damit es für alle Webseiten ausreicht).


    Allerdings ist es auch komisch, dass ein voller OPcache zu SEGFAULTS führt. Aktuell tendiere ich zwischen einem Bug im OPcache oder fehlerhafte Configs meinerseits.



    Über jede Hilfe bin ich dankbar...

  • PS: Das Problem mit den SEGFAULTS - was auf der Webseite mit einem 500er endet - betrifft auch nur PHP7.4. Die 7.3er Version hat diese Probleme nicht.


    Der OPcache sorgt für ca. 400% Performancesteigerung - daher würde ich ungern darauf verzichten.

  • Die aus meiner Sicht einfachste und sauberste Lösung wäre:
    * Statt mehreren Pools, mehrere PHP FPM Master Prozesse verwenden (idealerweise in einem Container).

    Das hat zudem den Vorteil, dass eine Webseite nicht gleich das PHP von allen anderen Seiten abschießt (schon oft genug selbst erlebt) und die Auswahl an PHP Versionen leichter macht.


    Opcache ist halt ein Shared Memory - mit all seinen Vor- und Nachteilen. Der Betrieb von Containern ist dank so vieler Tools so einfach geworden, dass ich das gerade in solchen Umgebungen sehr empfehlen würde.

  • Danke für die schnelle Antwort.

    Für jede Webseite einen eigenen Container bzw. Master Prozess wird aber ordentlich am RAM "ziehen".

    Eigene Master-Prozesse wären hier mein bevorzugter Weg. Muss ich mal mit auseinandersetzen.


    So wie ich das bis dato sehe, ist es ja nur eine Kopie + Anpassung der "/etc/php/X.X/fpm/php-fpm.conf" und "/etc/init.d/phpX.X-fpm".

    Das sollte man mit kleinen Bash Skripten schnell automatisieren können.


    PS:

    Bis dato hatte ich noch nie Probleme mit den Pools im Hinblick auf "Eine Webseite killt alle anderen". Das eine Webseite sich selbst mal abgeschossen hat, ja klar (z.B. durch Codefehler). Auf andere Pools ist es aber noch nie übergesprungen.