Tenho uma aplicação Laravel rodando em produção, e existem algumas APIs que são bastante utilizadas. Algo estava criando um gargalo e paralisava nossos servidores (3 com Load Balancer). Depois de otimizar o básico no Laravel, armazenar configurações em cache, rotas, dados e assim por diante, até mesmo resolver todos os problemas n+1, ainda estávamos tendo problemas em horários de pico. Alguém sugeriu que executássemos strace em um dos trabalhadores do nginx para ver o que está acontecendo no nível do sistema, então fizemos, e bastante interessante, há muitas chamadas de sistema redundantes onde o nginx tenta encontrar arquivos quando APIs são chamadas:
Parte do rastreamento:
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
Agora, a API é chamada com o ID 3d4f7518e04e9
neste caso e tenta percorrer os diretórios para encontrar esse arquivo. Mas não é um arquivo, é uma API. Executamos o strace por menos de 30 segundos e temos 5 mil chamadas que não fazem sentido para mim.
Então, essas ligações são necessárias? Acho que não, mas diga-me se estou errado. E se eu estiver certo, como posso configurar melhor meu nginx para que essas chamadas possam ser "detectadas a tempo" e resolvidas adequadamente. Qualquer ideia é bem-vinda. :)
PS: Também tentamos o apache com configuração semelhante, aparece o mesmo problema no strace.
Editar: Eu simplesmente preciso de algum tipo de diretiva de localização na configuração do meu site para resolver isso? Estou usando o conf nginx básico dos documentos oficiaishttps://laravel.com/docs/8.x/deployment#nginxcom mais algumas adições como:
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;
EDITAR:
location / {
try_files $uri $uri/ /index.php?$query_string;
}
Eu tentei arquivos sugeridos por Danila Vershinin em uma resposta
Responder1
Parece que você está lidando com try_files
um problema de desempenho. Você pode se livrar de stat
chamadas de sistema desnecessáriaseliminandotry_files
da sua configuração.
A try_files
diretiva fornece um padrão simples e agradável para a criação de um site amigável para SEO.
No entanto, a desvantagem dessa simplicidade é o custo adicional de stat
chamadas de sistema desnecessárias.
Como você sabe que, por exemplo, todos /api/
os URLs devem ser roteados através do seu PHP, não há necessidade de verificar a existência de nenhum arquivo e você pode rotear através do seu arquivo de inicialização do Laravel incondicionalmente, por exemplo:
location /api/ {
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
include fastcgi_params;
fastcgi_pass unix:/var/run/php-fpm/example.com.sock;
}
Além disso, em geral, você deseja ter informações de cache do NGINX sobre a existência de arquivos/diretórios. Isto pode ser conseguido atravésopen_file_cache.