it-swarm.com.de

502 Gateway-Fehler unter hoher Last (nginx/php-fpm)

Ich arbeite für eine ziemlich geschäftige Internetseite, auf der es oft zu sehr hohen Verkehrsspitzen kommt. Während dieser Spitzen werden Hunderte von Seiten pro Sekunde angefordert und dies führt zu zufälligen 502 Gateway-Fehlern.

Jetzt führen wir Nginx (1.0.10) und PHP-FPM auf einer Maschine mit 4xSAS15k-Laufwerken (raid10) mit einer 16-Kern-CPU und 24 GB DDR3-RAM aus. Außerdem verwenden wir die neueste Xcache-Version. Die Datenbank befindet sich auf einem anderen Computer, die Auslastung dieses Computers ist jedoch sehr gering und es treten keine Probleme auf.

Unter normaler Last läuft alles perfekt, die Systemlast liegt unter 1 und der PHP-FPM-Statusbericht zeigt nie wirklich mehr als 10 aktive Prozesse gleichzeitig an. Es sind immer noch ca. 10 GB RAM verfügbar. Unter normaler Last verarbeitet die Maschine ungefähr 100 Seitenaufrufe pro Sekunde.

Das Problem tritt auf, wenn große Verkehrsspitzen eintreffen und Hunderte Seitenaufrufe pro Sekunde von der Maschine angefordert werden. Ich stelle fest, dass der FPM-Statusbericht dann bis zu 50 aktive Prozesse anzeigt, aber dies liegt immer noch weit unter den 300 von uns konfigurierten Verbindungen. Während dieser Spitzen meldet der Nginx-Status bis zu 5000 aktive Verbindungen anstelle des normalen Durchschnitts von 1000.

OS Info: CentOS Release 5.7 (endgültig)

CPU: Intel (R) Xeon (R) CPU E5620 @ 2.40GH (16 Kerne)

php-fpm.conf

daemonize = yes
listen = /tmp/fpm.sock
pm = static
pm.max_children = 300
pm.max_requests = 1000

Ich habe rlimit_files nicht eingerichtet, da meines Wissens das System standardmäßig verwendet werden sollte, wenn Sie dies nicht tun.

fastcgi_params (nur Werte zur Standarddatei hinzugefügt)

fastcgi_connect_timeout 60;
fastcgi_send_timeout 180;
fastcgi_read_timeout 180;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
fastcgi_intercept_errors on;

fastcgi_pass            unix:/tmp/fpm.sock;

nginx.conf

worker_processes        8;
worker_connections      16384;
sendfile                on;
tcp_nopush              on;
keepalive_timeout       4;

Nginx verbindet sich über Unix Socket mit FPM.

sysctl.conf

net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 1
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.tcp_timestamps = 0
net.ipv4.conf.all.rp_filter=1
net.ipv4.conf.default.rp_filter=1
net.ipv4.conf.eth0.rp_filter=1
net.ipv4.conf.lo.rp_filter=1
net.ipv4.ip_conntrack_max = 100000

limits.conf

* soft nofile 65536
* hard nofile 65536

Dies sind die Ergebnisse für die folgenden Befehle:

ulimit -n
65536

ulimit -Sn
65536

ulimit -Hn
65536

cat /proc/sys/fs/file-max
2390143

Frage: Wenn PHP-FPM nicht über genügend Verbindungen verfügt, die Auslastung immer noch niedrig ist und genügend RAM zur Verfügung steht, welcher Engpass diese zufälligen 502-Gateway-Fehler bei hohem Datenverkehr verursachen könnte ?

Hinweis: Standardmäßig waren die ulimits dieser Maschine 1024, da ich sie in 65536 geändert habe, habe ich die Maschine nicht vollständig neu gestartet, da es sich um eine Produktionsmaschine handelt und dies zu viel Ausfallzeit bedeuten würde.

43
Mr.Boon

Das sollte es beheben ...

Sie haben: fastcgi_buffers 4 256k;

Ändern Sie es in: fastcgi_buffers 256 16k; // 4096 k insgesamt

Setzen Sie auch fastcgi_max_temp_file_size 0 , um die Pufferung auf der Festplatte zu deaktivieren, wenn die fastcgi-Puffer zu hoch werden.

24
Timothy Perez

Unix-Socket akzeptiert standardmäßig 128 Verbindungen. Es ist gut, diese Zeile in /etc/sysctl.conf zu setzen.

net.core.somaxconn = 4096
21
kait

Wenn es in einigen Fällen nicht hilft, verwenden Sie die normale Port-Bindung anstelle von Socket, da Socket auf 300+ neue Anforderungen blockieren kann, die dazu führen, dass Nginx 502 anzeigt.

1
Misiek

@Herr. Segen

Ich habe 8 Core 14 GB RAM. Das System gibt jedoch häufig ein Timeout für Gateway aus.
Das Update unter dem Fix konnte das Problem auch nicht lösen. Immer noch auf der Suche nach besseren Lösungen.

Sie haben: fastcgi_buffers 4 256k;

Ändern Sie es in: 

fastcgi_buffers 256 16k; // 4096 k insgesamt

Setzen Sie auch fastcgi_max_temp_file_size 0, , wodurch die Pufferung auf der Festplatte deaktiviert wird, wenn die Antworten Ihre fastcgi-Puffer überschreiten.

Vielen Dank.

0
Bhavin Visariya