Nginx

Nginx 記憶體符號連結

  • May 5, 2017

我的網路伺服器上有一個部署系統,每次部署應用程序時,它都會創建一個新的時間戳目錄並將“目前”符號連結到新目錄。這一切在 apache 上執行良好,非常棒,但是在我設置的新 nginx 伺服器上,它看起來像是來自“舊”部署的腳本正在執行,而不是新的符號連結腳本。

我已經閱讀了一些有關如何解決此問題的教程和文章,但沒有太多資訊,似乎沒有任何效果。這是我的虛擬主機文件:

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;
   }
}

這是我的 fastcgi_params:

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;

如果有人可以幫助我解決這個問題,我將不勝感激,因為目前每個部署都涉及刪除以前的部署。系統是 Ubuntu 14.04.5 LTS;PHP 7.1 ; Nginx nginx/1.4.6 (Ubuntu)

Embedded Variables , : 與目前請求的別名$realpath_root指令的值相對應的絕對路徑名,所有符號連結都解析為真實路徑

使用$realpath_root代替的解決方案$document_root是在問答網站和論壇周圍複製粘貼;實際上很難避免找到它。然而,我只看過Rasmus Lerdorf很好地解釋過一次。值得分享,因為它描述了它為什麼起作用以及何時應該使用它。

因此,當您通過 Capistrano 等在文件根目錄上進行符號連結交換的東西進行部署時,您希望所有新請求都獲取新文件,但您不想在部署發生時搞砸目前正在執行的請求。創建一個健壯的部署環境真正需要的是讓您的 Web 伺服器負責這一點。Web 伺服器是理解新請求何時開始的堆棧的一部分。操作碼記憶體在堆棧中太深而無法知道或關心。

使用 nginx,這非常簡單。只需將其添加到您的配置中:

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

這告訴 nginx realpath 解析 docroot 符號連結,這意味著據您的 PHP 應用程序所知,符號連結的目標是真實的 document_root。現在,一旦請求開始,nginx 將解析符號連結,並且在請求期間它將使用相同的 docroot 目錄,即使符號連結切換發生在請求中間。這完全消除了這裡描述的症狀,這是正確的方法。這不是可以在 opcache 級別解決的問題。

Kanishk Dudeja 對此有疑問,並添加了一個有用的通知:確保這些更改實際上處於最終配置中,即在此之後include fastcgi_params;會覆蓋它們。

引用自:https://serverfault.com/questions/848503