Simbol caching nginx

12

Saya memiliki sistem penyebaran di server web saya, setiap kali sebuah aplikasi dikerahkan, ia menciptakan direktori timestamped baru dan menghubungkan "saat ini" dengan direktori baru. Ini semua bekerja dengan baik dan hebat pada apache, tetapi pada server nginx baru yang saya atur, sepertinya skrip dari penyebaran "lama" sedang dijalankan alih-alih yang baru disinkronkan.

Saya telah membaca beberapa tutorial dan posting tentang cara mengatasi ini tetapi tidak ada banyak info dan sepertinya tidak ada yang berhasil. Ini file vhost saya:

server {
    listen 80;

    server_name ~^(www\.)?(?<sname>.+?).testing.domain.com$;
    root /var/www/$sname/current/public;
    index index.html index.htm index.php;

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~* \.(jpg|jpeg|gif|png|bmp|ico|pdf|flv|swf|exe|html|htm|txt|css|js) {
        add_header        Cache-Control public;
        add_header        Cache-Control must-revalidate;
        expires           7d;
    }

    location ~ \.php$ {
        #fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php/php7.1-fpm.sock;
        include fastcgi_params;
        fastcgi_param DOCUMENT_ROOT $realpath_root;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_index index.php;
    }

    location ~ /\.ht {
        deny all;
    }
}

dan ini fastcgi_params saya:

fastcgi_param   SCRIPT_FILENAME         $document_root$fastcgi_script_name;
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   REQUEST_URI     $request_uri;
fastcgi_param   DOCUMENT_URI        $document_uri;
fastcgi_param   DOCUMENT_ROOT           $realpath_root;
fastcgi_param   SERVER_PROTOCOL     $server_protocol;

fastcgi_param   GATEWAY_INTERFACE   CGI/1.1;
fastcgi_param   SERVER_SOFTWARE     nginx/$nginx_version;

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_param   HTTPS           $https if_not_empty;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param   REDIRECT_STATUS     200;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_script_name;

Saya akan sangat menghargai jika seseorang dapat membantu saya dalam hal ini karena saat ini setiap penyebaran melibatkan penghapusan penempatan sebelumnya. Sistem adalah Ubuntu 14.04.5 LTS; PHP 7.1; Nginx nginx / 1.4.6 (Ubuntu)

Auris
sumber

Jawaban:

22

Variabel tertanam , $realpath_root: nama path absolut yang sesuai dengan akar atau alias nilai direktif untuk permintaan saat ini, dengan semua link simbolik memutuskan untuk jalur nyata

Solusi menggunakan $realpath_rootalih-alih $document_rootdisalin di seluruh situs dan forum Tanya Jawab; sebenarnya sulit untuk menghindari menemukannya. Namun, saya hanya pernah melihatnya dengan baik sekali dijelaskan oleh Rasmus Lerdorf . Layak untuk dibagikan karena ini menjelaskan mengapa ini bekerja dan kapan harus digunakan.

Jadi, ketika Anda menggunakan sesuatu seperti Capistrano yang melakukan symlink swap pada root dokumen, Anda ingin semua permintaan baru untuk mendapatkan file baru, tetapi Anda tidak ingin mengabaikan permintaan yang saat ini dieksekusi saat penyebaran sedang terjadi. Apa yang benar-benar Anda butuhkan untuk menciptakan lingkungan penyebaran yang kuat adalah membuat server web Anda bertanggung jawab atas ini. Server web adalah bagian dari tumpukan yang mengerti ketika permintaan baru dimulai. Tembolok opcode terlalu dalam di tumpukan untuk mengetahui atau peduli tentang itu.

Dengan nginx ini cukup sederhana. Cukup tambahkan ini ke konfigurasi Anda:

fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;

Ini memberitahu nginx untuk menjalankan realpath menyelesaikan makna symlink docroot yang sejauh yang diketahui aplikasi PHP Anda, target symlink jika document_root yang asli. Sekarang, setelah permintaan dimulai, nginx akan menyelesaikan symlink seperti yang ada pada saat itu dan selama durasi permintaan itu akan menggunakan direktori docroot yang sama, bahkan jika sakelar symlink terjadi pada pertengahan permintaan. Ini sepenuhnya menghilangkan gejala yang dijelaskan di sini dan itu adalah pendekatan yang benar. Ini bukan sesuatu yang bisa diselesaikan di level opcache.

Kanishk Dudeja memiliki masalah dengan ini dan menambahkan pemberitahuan yang berguna: pastikan perubahan ini benar-benar berada dalam konfigurasi akhir, yaitu setelah include fastcgi_params;itu jika tidak mengesampingkannya.

Esa Jokinen
sumber
Hai, ini adalah jawaban yang bagus, tetapi jika Anda perhatikan di konfigurasi saya, saya punya fastcgi_param DOCUMENT_ROOT $ realpath_root; fastcgi_param SCRIPT_FILENAME $ document_root $ fastcgi_script_name; disertakan setelah fastcgi_params, dan ini sebenarnya tidak membantu. Ketika saya me-restart php-fpm symlinks terselesaikan. Apakah ini menunjukkan bahwa saya memiliki masalah caching php?
Auris
Merevisi. Anda SCRIPT_FILENAMEpunya $document_root, tidak $realpath_root.
Esa Jokinen
Hmm ... tetapi DOCUMENT_ROOTdiatur $realpath_rootsedemikian rupa sehingga saya memahaminya, seharusnya rantai menarik nilai atau saya benar-benar salah dan DOCUMENT_ROOTtidak terkait dengan$document_root
Auris
1
Hai, terima kasih banyak atas jawaban dan penjelasan Anda, kesalahan saya adalah asumsi yang DOCUMENT_ROOTmempengaruhi$document root
Auris
2
Saya menggunakan Apache + php-fpm di server dengan masalah ini dan membersihkan opcached pada deploy bekerja untuk saya, kami memiliki skrip bash untuk penyebaran bukan Capistrano. Saya pikir ini adalah solusi yang lebih sederhana dan ini adalah praktik yang baik untuk menghapus opcache Anda saat digunakan. Esa, terima kasih atas tautan ke komentar Rasmus, itu emas!
Carlos Mafla
3

Dari /unix/157022/make-nginx-follow-symlinks , tampaknya Anda mungkin dapat mengatasi masalah ini dengan mengubah

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

untuk

fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;

(Yaitu mengubah jalur dari $document_rootke $realpath_root).

Saya tidak memiliki akses ke server nginx saat ini untuk mengonfirmasi hal ini (server rumah saya sedang menjalani pembangunan kembali), tetapi solusinya tampaknya dikolaborasikan oleh https://medium.com/@kanishkdudeja/truly-atomic-deployments -dengan-nginx-dan-php-fpm-aed8a8ac1cd9 .

Pak
sumber