Nextcloud performance
Nextcloud fühlte sich träge an. Nicht dauerhaft, aber das Wechseln zwischen Dashboard und einer anderen App dauerte regelmäßig drei bis zehn Sekunden. Danach lief es flüssig.
Diagnose
Zuerst Redis geprüft, weil der als Session- und File-Locking-Cache läuft:
redis-cli info stats | grep -E 'keyspace_hits|keyspace_misses'
Ergebnis: 4,6 Millionen Hits, 379.000 Misses, Trefferquote rund 92 %. Redis war in Ordnung.
Dann die PHP-FPM-Konfiguration:
grep -E 'pm\b|pm\.' /etc/php/8.3/fpm/pool.d/www.conf
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
Fünf Worker maximal, einer davon mindestens im Leerlauf. Bei einem Server mit 62 GB RAM und einem Nextcloud-Cronjob alle zehn Minuten ist das knapp.
Dann OPcache:
grep -E 'opcache.enable|opcache.memory_consumption' /etc/php/8.3/fpm/php.ini
;opcache.enable=1
;opcache.memory_consumption=128
Alles auskommentiert.
OPcache war komplett deaktiviert. Nextcloud hat bei jedem einzelnen Request alle PHP-Dateien neu geparst und kompiliert. Das war die Ursache.
Lösung
In
/etc/php/8.3/fpm/php.ini:
opcache.enable=1
opcache.enable_cli=0
opcache.memory_consumption=256
opcache.interned_strings_buffer=32
opcache.max_accelerated_files=10000
opcache.revalidate_freq=60
opcache.save_comments=1
In /etc/php/8.3/fpm/pool.d/www.conf:
pm.max_children = 20
pm.start_servers = 5
pm.min_spare_servers = 4
pm.max_spare_servers = 10
Neu laden:
systemctl reload php8.3-fpm
Hintergrund
OPcache speichert kompilierte PHP-Bytecodes im Shared Memory. Ohne OPcache kompiliert PHP bei jedem Request neu, mit OPcache passiert das einmal und wird für alle Worker wiederverwendet. Für eine Anwendung wie Nextcloud mit hunderten PHP-Dateien macht das einen spürbaren Unterschied.
pm.min_spare_serversbestimmt, wie viele FPM-Worker im Leerlauf bereitstehen. Zu niedrige Werte bedeuten: kein freier Worker vorhanden, neuer muss gestartet werden, OPcache für den neuen Worker muss erst aufgewärmt werden. Der erste Request nach einer Pause zahlt dafür den Preis.
ISPConfig-Umgebungen
Wer ISPConfig einsetzt, hat zwei Stellen für PHP-Einstellungen:
/etc/php/8.3/fpm/php.ini– globale Konfiguration, gilt für alle Sites ohne eigene Einstellungen- ISPConfig-Webinterface pro Site unter "PHP-Optionen" – wird als
php_admin_valuein den FPM-Pool geschrieben und überschreibt die globale php.ini
Im konkreten Fall hatte ISPConfig für die Nextcloud-Site bereits OPcache-Parameter gesetzt (
memory_consumption,interned_strings_bufferusw.), aberopcache.enable=1fehlte. Das Ergebnis: OPcache war konfiguriert, aber nicht aktiv.
Die Korrektur in der globalen php.ini hat opcache.enable=1 gesetzt und damit OPcache für alle Sites auf dem Server aktiviert, die keine eigenen PHP-Optionen in ISPConfig haben.
Beim Debuggen von OPcache-Problemen immer beide Stellen prüfen. ISPConfig gewinnt im Zweifelsfall, weil es später in der Ladekette greift.