API が呼び出されたときに冗長なシステム コールを減らすために nginx をより適切に構成するにはどうすればよいですか?

API が呼び出されたときに冗長なシステム コールを減らすために nginx をより適切に構成するにはどうすればよいですか?

私は本番環境で Laravel アプリケーションを実行していますが、よく使用される API がいくつかあります。何かがボトルネックとなり、サーバー (ロード バランサーで 3 台) が停止していました。Laravel の基本を最適化し、構成、ルート、データなどをキャッシュし、n+1 の問題をすべて解決した後でも、ピーク時には問題が発生していました。システム レベルで何が起こっているかを確認するために、nginx ワーカーの 1 つで strace を実行するよう提案されたので、実行してみました。興味深いことに、API が呼び出されたときに nginx がファイルを見つけようとする冗長なシステム コールが多数ありました。

トレースの一部:

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

この場合、 API は ID で呼び出され3d4f7518e04e9、代わりにディレクトリをループしてそのファイルを見つけようとします。しかし、それはファイルではなく、API です。strace を 30 秒未満実行しましたが、このような呼び出しが 5,000 回発生しましたが、意味がわかりません。

では、これらの呼び出しは必要なのでしょうか? 私はそうは思いませんが、間違っていたら教えてください。そして、私が正しい場合、これらの呼び出しが「時間内にキャッチ」され、適切に解決されるように、nginx をどのように構成すればよいでしょうか。どんなアイデアでも歓迎します。:)

PS: 同様の設定で Apache も試しましたが、strace で同じ問題が発生します。

編集: これを解決するには、サイトの設定に何らかの場所の指示を追加するだけでいいのでしょうか? 私は公式ドキュメントの基本的なnginxの設定を使用していますnginx のデプロイさらに次のような追加事項があります:

    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;

編集:

location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

Danila Vershininが回答で示唆したように、私は試用ファイルを持っています

答え1

パフォーマンスの問題を抱えているようです。不要なシステムコールtry_filesを削除するには、stat排除するtry_files設定から。

このtry_filesディレクティブは、SEO に適した Web サイトを作成するためのシンプルで優れた定型文を提供します。

statただし、このシンプルさの欠点は、不要なシステム コールによる追加コストが発生することです。

たとえば、すべての/api/URL は PHP 経由でルーティングされる必要があることがわかっているので、そこにファイルが存在するかどうかを確認する必要はなく、Laravel ブートストラップ ファイルを無条件にルーティングできます。例:

location /api/ {
    fastcgi_param SCRIPT_FILENAME $document_root/index.php;
    include fastcgi_params;
    fastcgi_pass unix:/var/run/php-fpm/example.com.sock;
}

さらに、一般的には、ファイルやディレクトリの存在に関するNGINXのキャッシュ情報が必要です。これは、次のようにして実現できます。オープンファイルキャッシュ

関連情報