Ich habe eine Laravel-Anwendung in der Produktion laufen und es gibt einige APIs, die häufig verwendet werden. Irgendetwas verursachte einen Engpass und das führte dazu, dass unsere Server (3 mit Load Balancer) blockiert wurden. Nachdem wir die Grundlagen in Laravel optimiert, Konfiguration, Routen, Daten usw. zwischengespeichert und sogar alle n+1-Probleme gelöst hatten, hatten wir in Spitzenzeiten immer noch Probleme. Jemand schlug vor, dass wir strace auf einem der Nginx-Worker ausführen, um zu sehen, was auf Systemebene passiert, also taten wir das und interessanterweise gibt es viele redundante Systemaufrufe, bei denen Nginx versucht, Dateien zu finden, wenn APIs aufgerufen werden:
Teil der Ablaufverfolgung:
240498 stat("/var/www/html/myProject/current/public/APIRequest/3d4f7518e04e9", 0x7ffc7ee6ff70) = -1 ENOENT (No such file or directory)
240498 stat("/var/www/html/myProject/current/public/APIRequest/3d4f7518e04e9", 0x7ffc7ee6ff70) = -1 ENOENT (No such file or directory)
240498 lstat("/var", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
240498 lstat("/var/www", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
240498 lstat("/var/www/html", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
240498 lstat("/var/www/html/myProject", {st_mode=S_IFDIR|0777, st_size=4096, ...}) = 0
240498 lstat("/var/www/html/myProject/current", {st_mode=S_IFLNK|0777, st_size=48, ...}) = 0
240498 readlink("/var/www/html/myProject/current", "/var/www/html/myProject/release"..., 4095) = 48
240498 lstat("/var", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
240498 lstat("/var/www", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
240498 lstat("/var/www/html", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
240498 lstat("/var/www/html/myProject", {st_mode=S_IFDIR|0777, st_size=4096, ...}) = 0
240498 lstat("/var/www/html/myProject/releases", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0
240498 lstat("/var/www/html/myProject/releases/20201202085755", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0
240498 lstat("/var/www/html/myProject/releases/20201202085755/public", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0
Jetzt wird die API in diesem Fall mit der ID aufgerufen 3d4f7518e04e9
und versucht, die Verzeichnisse zu durchlaufen, um stattdessen diese Datei zu finden. Aber es ist keine Datei, es ist eine API. Wir haben strace weniger als 30 Sekunden lang ausgeführt und haben 5.000 solcher Aufrufe, die für mich keinen Sinn ergeben.
Sind diese Aufrufe also notwendig? Ich glaube nicht, aber sagen Sie mir, wenn ich falsch liege. Und wenn ich Recht habe, wie kann ich mein Nginx besser konfigurieren, damit diese Aufrufe „rechtzeitig abgefangen“ und entsprechend aufgelöst werden können. Alle Ideen sind willkommen. :)
PS: Wir haben Apache auch mit ähnlicher Konfiguration ausprobiert, in Strace tritt das gleiche Problem auf.
Edit: Brauche ich einfach eine Art Standortanweisung in meiner Site-Konfiguration, um das Problem zu lösen? Ich verwende die grundlegende Nginx-Konfiguration aus den offiziellen Dokumentenhttps://laravel.com/docs/8.x/deployment#nginxmit ein paar weiteren Ergänzungen wie:
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_buffer_size 128k;
fastcgi_buffers 256 16k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
}
location ~ /\.(?!well-known).* {
deny all;
}
client_body_buffer_size 10K;
client_header_buffer_size 1k;
client_max_body_size 8m;
large_client_header_buffers 4 16k;
client_body_timeout 12;
client_header_timeout 12;
keepalive_timeout 15;
send_timeout 10;
BEARBEITEN:
location / {
try_files $uri $uri/ /index.php?$query_string;
}
Ich habe Try-Dateien, wie von Danila Vershinin in einer Antwort vorgeschlagen
Antwort1
Es sieht so aus, als hätten Sie ein Leistungsproblem. Sie können unnötige Systemaufrufe try_files
vermeiden, indem Siestat
Beseitigungtry_files
aus Ihrer Konfiguration.
Die try_files
Richtlinie bietet einen schönen und einfachen Standardtext zum Erstellen einer SEO-freundlichen Website.
Diese Einfachheit hat jedoch auch eine Kehrseite: Der Mehraufwand durch unnötige stat
Systemaufrufe.
Da Sie beispielsweise wissen, dass alle /api/
URLs über Ihr PHP geleitet werden müssen, müssen Sie dort nicht auf das Vorhandensein von Dateien prüfen und können bedingungslos über Ihre Laravel-Bootstrap-Datei leiten, z. B.:
location /api/ {
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
include fastcgi_params;
fastcgi_pass unix:/var/run/php-fpm/example.com.sock;
}
Darüber hinaus möchten Sie im Allgemeinen NGINX-Cache-Informationen über die Existenz von Dateien/Verzeichnissen haben. Dies kann erreicht werden durchDateicache öffnen.