Was ist falsch in meiner PHP-Fpm-Konfiguration?

8

Ich habe einen 64-Bit-Server, aber nur 256 MB RAM. Also bin ich mit Fast-CGI auf den Nginx-Server umgezogen, um eine Verbindung zu PHP herzustellen. Ich habe PHP 5.3.6 ausgeführt.

Das Problem ist, dass ich alle zwei oder drei Tage, wenn ich versuche, auf eine PHP-Seite zuzugreifen, einen serverinternen Fehler erhalte. Die einzige Möglichkeit besteht darin, php-fpm manuell neu zu starten. Dies bedeutet, dass ich einige falsche Parameter hätte einstellen sollen, die dazu führen, dass es erstickt. Unten habe ich die relevanten Konfigurationen aufgelistet.

/etc/php-fpm.conf: -

include=/etc/php-fpm.d/*.conf
log_level = error
;emergency_restart_threshold = 0
;emergency_restart_interval = 0
;process_control_timeout = 0

/etc/php-fpm.d/www.conf: -

[www]
pm = dynamic
pm.max_children = 10
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 5
pm.max_requests = 500

/etc/nginx/php.conf: -

location ~ \.php {
        fastcgi_param  QUERY_STRING       $query_string;
        fastcgi_param  REQUEST_METHOD     $request_method;
        fastcgi_param  CONTENT_TYPE       $content_type;
        fastcgi_param  CONTENT_LENGTH     $content_length;

        fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
        fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
        fastcgi_param  REQUEST_URI        $request_uri;
        fastcgi_param  DOCUMENT_URI       $document_uri;
        fastcgi_param  DOCUMENT_ROOT      $document_root;
        fastcgi_param  SERVER_PROTOCOL    $server_protocol;

        fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
        fastcgi_param  SERVER_SOFTWARE    nginx;

        fastcgi_param  REMOTE_ADDR        $remote_addr;
        fastcgi_param  REMOTE_PORT        $remote_port;
        fastcgi_param  SERVER_ADDR        $server_addr;
        fastcgi_param  SERVER_PORT        $server_port;
        fastcgi_param  SERVER_NAME        $server_name;

        fastcgi_pass unix:---some-location---;
}

Update 1

Und ich habe vier Nginx-Prozesse ausgeführt. Im Durchschnitt benötigt jeder PHP-Fpm-Prozess 35 MB RAM (Größe des virtuellen Speichers jeweils 320 MB). Ich habe auch einen MySQL-Prozess ausgeführt.

Update 2

Ich habe vergessen, die Protokolle einzufügen.

PHP-Fpm-Fehlerprotokoll: -

WARNING: [pool www] seems busy (you may need to increase start_servers, or min/max_spare_servers), spawning 8 children, there are 1 idle, and 7 total children
WARNING: [pool www] server reached max_children setting (10), consider raising it
NOTICE: Terminating ...

php-fpm www.error log: -

PHP Fatal error:  Allowed memory size of 33554432 bytes exhausted (tried to allocate 122880 bytes) in /home/webadmin/blog.applegrew.com/html/wordpress/wp-content/plugins/jetpack/class.jetpack-signature.php on line 137
PHP Fatal error:  Allowed memory size of 33554432 bytes exhausted (tried to allocate 122880 bytes) in /home/webadmin/blog.applegrew.com/html/wordpress/wp-content/plugins/jetpack/class.jetpack-signature.php on line 137
PHP Fatal error:  Allowed memory size of 33554432 bytes exhausted (tried to allocate 122880 bytes) in /home/webadmin/blog.applegrew.com/html/wordpress/wp-content/plugins/jetpack/class.jetpack-signature.php on line 137
AppleGrew
quelle

Antworten:

17

Eine spontane Empfehlung wäre, die eingestellten Werte zu senken - wahrscheinlich zu halbieren.

Sie haben: pm.max_children = 10 Wenn Sie 35MB / process = 350MB sagen; Auf einer 256-MB-Box bedeutet dies entweder viel Austausch oder Ihnen geht der Speicher aus - beides ist nicht gut.

Ich würde sagen, nehmen Sie mindestens 100 MB für andere Prozesse, vielleicht sogar 150 MB, um sicher zu gehen, und teilen Sie diese Zahl dann durch 35 MB, um Ihre max_children zu erhalten. Halten Sie alle anderen Zahlen in einer Linie:

pm = dynamic
pm.max_children = 4
pm.start_servers = 1
pm.min_spare_servers = 1
pm.max_spare_servers = 2
pm.max_requests = 500

Stoppen Sie PHP-FPM und führen Sie es aus free, um eine Vorstellung von Ihrem verfügbaren Speicher zu erhalten. Teilen Sie es durch Ihre 35 MB, um Ihre max_children zu erhalten.

Je nachdem, wie viel Speicher MySQL benötigt, müssen Sie möglicherweise max_children auf 3 setzen.

Ich finde, dass PHP-FPM-Prozesse viel Speicher gemeinsam nutzen. Machen Sie ein schnelles Experiment, um festzustellen, wie viel tatsächlich verwendet wird. Stoppen Sie PHP-FPM und führen Sie es aus free. Starten Sie PHP-FPM, besuchen Sie einige häufig verwendete Seiten (erforderlich, da der Speicher abhängig von den geladenen Seiten zunimmt) und überprüfen Sie den insgesamt verwendeten Speicher. Verwenden Sie erneut free- dividieren Sie die Differenz durch die Anzahl der Prozesse. Es ist kein perfektes System, aber ich finde es ziemlich genau (manchmal ist die Datenspalte oben auch nicht schlecht).

cyberx86
quelle
Ich mache einen Stopp freeund fange an. Ich teile diesen freien Speicher durch 35, um den zu erhalten max_children value. Ich habe den Zweck des letzten Absatzes nicht verstanden.
AppleGrew
Es scheint, dass ich nur maximal 2.3 PHP-Prozesse unterstützen kann. : P Wie auch immer, ich habe jetzt max_childrenzu 3.
AppleGrew
a) Der Zweck des letzten Absatzes bestand darin, einen genaueren Wert für den Verbrauch eines PHP-Prozesses zu erhalten. Ich finde, dass der Wert von ps oder top nicht immer mit dem Abfall des verfügbaren Speichers übereinstimmt. Wenn Sie den verfügbaren Speicher finden, einige PHP-Prozesse ausführen und dann den verfügbaren Speicher erneut messen (anstatt den von den Prozessen verwendeten Speicher zu betrachten), können Sie einen alternativen (und möglicherweise besseren) Wert für die von jedem Prozess verwendete Speichermenge erhalten. b) Der von invarbrass vorgeschlagene Parameter memory_limit ist ebenfalls ein guter Vorschlag. c) Sehen Sie sich das Skript mysqltuner.pl an, es kann bei Ihrer DB-Konfiguration hilfreich sein.
Cyberx86
@ cyberx86, welchen Wert freeberücksichtigen Sie? Die aus der Zeile '- / + Puffer / Cache', die für den Festplatten-Cache verwendet wird, aber für Apps tatsächlich kostenlos ist?
Roman Newaza
@RomanNewaza - Ja, Sie möchten den für die Anwendung verfügbaren Speicher anzeigen, also verwenden Sie den Eintrag für 'kostenlos' unter '- / + Puffer / Cache'.
Cyberx86
6

Ihr PHP-Fpm-Setup scheint in Ordnung zu sein.

Der Server, den Sie ausführen, ist jedoch etwas ressourcenbeschränkt. Aus den Protokollen geht hervor, dass PHP-Prozesse den verfügbaren Speicher erschöpfen.

Hinzufügen zu den Vorschlägen von cyberx86:

Sie können versuchen, den Parameter memory_limit in der Datei php.ini zu bearbeiten (siehe hier ) (obwohl ich nicht sicher bin, ob es viel Gutes bringt).

Angesichts des geringen Systemspeichers sollten Sie ernsthaft in Betracht ziehen, auf ein 32-Bit-Betriebssystem umzusteigen. Die Verwendung eines x64-Betriebssystems schadet Ihnen eher, als dass Sie davon profitieren.

Wenn Sie keinen InnoDB-Speicher in Ihrer MySQL-Datenbank verwenden, können Sie auch InnoDB in Ihrer my.cnf deaktivieren. Dadurch werden weitere 100 MB RAM eingespart.

Lowendbox bietet ein großartiges Tutorial zum Optimieren von Servern für eine Konfiguration mit wenig Arbeitsspeicher.

Invarbrass
quelle
Nun, meine Stimme ist heiser geworden, als ich versucht habe, mit meiner Hosting-Firma zu argumentieren, mir ein 32-Bit-Betriebssystem zur Verfügung zu stellen. Es scheint, dass diese Unternehmen im ganzen Netz nur 64-Bit anbieten. Ich habe nur eine Firma gefunden, die 32-Bit-Betriebssysteme anbietet, aber diese sind viel teurer.
AppleGrew
3

Ein sehr praktischer Befehl, um den von PHP belegten Speicher zu finden:

ps --no-headers -o "rss,cmd" -C php5-fpm | awk '{ sum+=$1 } END { printf ("%d%s\n", sum/NR/1024,"M") }'

Dann teilen Sie den RAM, den Sie PHP widmen möchten, und Sie haben Ihren max_children-Wert!

Sie können auch manuell (Sie müssen den Endpunkt-PHP-Status einrichten) oder mit Nagios überwachen.

Thomas Decaux
quelle
awk: fatal: division by zero attempted
Samayo
1
Bedeutet, dass Sie keinen php5-fpm-Prozess haben. Sie müssen den Namen des Prozesses "php5-fpm" ändern, um ihn an Ihren eigenen anzupassen.
Thomas Decaux
Ich habe diesen Befehl verwendet. ps --no-headers -o "rss,cmd" | grep php5-fpm | awk '{ sum+=$1 } END { printf ("%d%s\n", sum/NR/1024,"M") }'Irgendwie funktionieren die Optionen -C nicht.
Dieend
Versuchen Sie, den Befehl separat auszuführen (ich meine ps --no-headers -o "rss, cmd" zuerst etc ...), dies sollte leicht zu debuggen sein
Thomas Decaux