FastCGI介紹
FastCGI是從CGI發展改進而來的。傳統CGI接口方式的主要缺點是性能很差,因為每次HTTP服務器遇到動態程序時都需要重新啟動腳本解析器來執行解析,然后結果被返回給HTTP服務器。這在處理高並發訪問時,幾乎是不可用的。另外傳統的CGI接口方式安全性也很差,現在已經很少被使用了。
FastCGI接口方式采用C/S結構,可以將HTTP服務器和腳本解析服務器分開,同時在腳本解析服務器上啟動一個或者多個腳本解析守護進程。當HTTP服務器每次遇到動態程序時,可以將其直接交付給FastCGI進程來執行,然后將得到的結果返回給瀏覽器。這種方式可以讓HTTP服務器專一地處理靜態請求或者將動態腳本服務器的結果返回給客戶端,這在很大程度上提高了整個應用系統的性能。
Nginx不支持對外部程序的直接調用或者解析,所有的外部程序(包括PHP)必須通過FastCGI接口來調用。FastCGI接口在Linux下是socket,(這個socket可以是文件socket,也可以是ip socket)。為了調用CGI程序,還需要一個FastCGI的wrapper(wrapper可以理解為用於啟動另一個程序的程序),這個wrapper綁定在某個固定socket上,如端口或者文件socket。當Nginx將CGI請求發送給這個socket的時候,通過FastCGI接口,wrapper接納到請求,然后派生出一個新的線程,這個線程調用解釋器或者外部程序處理腳本並讀取返回數據;接着,wrapper再將返回的數據通過FastCGI接口,沿着固定的socket傳遞給Nginx;最后,Nginx將返回的數據發送給客戶端,這就是Nginx+FastCGI的整個運作過程。詳細的過程,如圖所示
快速通用網關接口(Fast Common Gateway Interface/FastCGI)是通用網關接口(CGI)的改進,描述了客戶端和服務器程序之間傳輸數據的一種標准。FastCGI致力於減少Web服務器與CGI程式之間互動的開銷,從而使服務器可以同時處理更多的Web請求。與為每個請求創建一個新的進程不同,FastCGI使用持續的進程來處理一連串的請求。這些進程由FastCGI進程管理器管理,而不是web服務器。
當進來一個請求時,Web 服務器把環境變量和這個頁面請求通過一個unix domain socket(都位於同一物理服務器)或者一個IP Socket(FastCGI部署在其它物理服務器)傳遞給FastCGI進程。
- step1. Web 服務器啟動時載入初始化FastCGI執行環境 。 例如IIS ISAPI、apache mod_fastcgi、nginx ngx_http_fastcgi_module、lighttpd mod_fastcgi
- step2. FastCGI進程管理器自身初始化,啟動多個CGI解釋器進程並等待來自Web 服務器的連接。啟動FastCGI進程時,可以配置以ip和UNIX 域socket兩種方式啟動。
- step3. 當客戶端請求到達Web 服務器時, Web 服務器將請求采用socket方式轉發到 FastCGI主進程,FastCGI主進程選擇並連接到一個CGI解釋器。Web 服務器將CGI環境變量和標准輸入發送到FastCGI子進程。
- step4. FastCGI子進程完成處理后將標准輸出和錯誤信息從同一socket連接返回Web 服務器。當FastCGI子進程關閉連接時,請求便處理完成。
- step5. FastCGI子進程接着等待並處理來自Web 服務器的下一個連接。
由於 FastCGI 程序並不需要不斷的產生新進程,可以大大降低服務器的壓力並且產生較高的應用效率。它的速度效率最少要比CGI 技術提高 5 倍以上。它還支持分布式的部署, 即 FastCGI 程序可以在web 服務器以外的主機上執行。
CGI 就是所謂的短生存期應用程序,FastCGI 就是所謂的長生存期應用程序。FastCGI像是一個常駐(long-live)型的CGI,它可以一直執行着,不會每次都要花費時間去fork一次(這是CGI最為人詬病的fork-and-execute 模式)。
nginx配置示例
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
這個配置的意思是 在瀏覽器中訪問的.php文件,實際讀取的是 $document_root(網站根目錄)下的.php文件 -- 也就是說當訪問127.0.0.1/index.php的時候,需要讀取網站根目錄下面的index.php文件
include fastcgi_params; fastcgi_params 文件中含有各個nginx常量的定義,默認情況 SCRIPT_FILENAME = $fastcgi_script_name
Nginx涉及三類配置文件
1. 基礎文件 conf/nginx.conf # 說明:nginx默認會引用該文件,該文件會做最通用的參數設置 2. fastcgi參數文件 conf/fastcgi.conf # 說明:fastcgi會設置所有站點通用參數 3. 站點文件 如:conf/vhost/a.com.conf 可以有多個,放在vhost文件夾下
nginx配置文件里指令的繼承關系:Nginx配置文件分為好多塊,常見的從外到內依次是「http」、「server」、「location」等等,缺省的繼承關系是從外到內,也就是說內層塊會自動獲取外層塊的值作為缺省值
conf/fastcgi.conf內容:
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 $document_root; fastcgi_param SERVER_PROTOCOL $server_protocol; fastcgi_param HTTPS $https if_not_empty; 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; # PHP only, required if PHP was built with --enable-force-cgi-redirect fastcgi_param REDIRECT_STATUS 200; # 用一個文件或狀態碼(=404)作為最后一個參數,如果是最后一個參數是文件,那么這個文件必須存在 try_files $fastcgi_script_name = 404; #可以自定義值,比如區分開發(dev)和生成環境(product),在php中用getenv('MY_ENV')或$_SERVER['MY_ENV']獲取 fastcgi_param MY_ENV "product"; #防跨站設置 fastcgi_param PHP_ADMIN_VALUE "open_basedir=$document_root/:/data/tmp/php/upload/:/proc/";
需要說明的:Nginx有兩份fastcgi配置文件,分別是舊的「fastcgi_params」和新的「fastcgi.conf」,它們沒有太大的差異,唯一的區別是后者比前者多了一行「SCRIPT_FILENAME」的定義,只需要引用一份新的配置文件fastcgi.conf即可
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;#腳本文件請求的路徑 fastcgi_param QUERY_STRING $query_string; #請求的參數;如?app=123 fastcgi_param REQUEST_METHOD $request_method; #請求的動作(GET,POST) fastcgi_param CONTENT_TYPE $content_type; #請求頭中的Content-Type字段 fastcgi_param CONTENT_LENGTH $content_length; #請求頭中的Content-length字段。 fastcgi_param SCRIPT_NAME $fastcgi_script_name; #腳本名稱 fastcgi_param REQUEST_URI $request_uri; #請求的地址不帶參數 fastcgi_param DOCUMENT_URI $document_uri; #與$uri相同。 fastcgi_param DOCUMENT_ROOT $document_root; #網站的根目錄。在server配置中root指令中指定的值 fastcgi_param SERVER_PROTOCOL $server_protocol; #請求使用的協議,通常是HTTP/1.0或HTTP/1.1。 fastcgi_param GATEWAY_INTERFACE CGI/1.1;#cgi 版本 fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;#nginx 版本號,可修改、隱藏 fastcgi_param REMOTE_ADDR $remote_addr; #客戶端IP fastcgi_param REMOTE_PORT $remote_port; #客戶端端口 fastcgi_param SERVER_ADDR $server_addr; #服務器IP地址 fastcgi_param SERVER_PORT $server_port; #服務器端口 fastcgi_param SERVER_NAME $server_name; #服務器名,域名在server配置中指定的server_name #fastcgi_param PATH_INFO $path_info;#可自定義變量 # PHP only, required if PHP was built with –enable-force-cgi-redirect #fastcgi_param REDIRECT_STATUS 200; 在php可打印出上面的服務環境變量 如:echo $_SERVER['MY_ENV']
Nginx中FastCGI參數的優化配置實例
在配置完成Nginx+FastCGI之后,為了保證Nginx下PHP環境的高速穩定運行,需要添加一些FastCGI優化指令。下面給出一個優化實例,將下面代碼添加到Nginx主配置文件中的HTTP層級
fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2 keys_zone=TEST:10m inactive=5m; fastcgi_connect_timeout 300; fastcgi_send_timeout 300; fastcgi_read_timeout 300; fastcgi_buffer_size 64k; fastcgi_buffers 4 64k; fastcgi_busy_buffers_size 128k; fastcgi_temp_file_write_size 128k; fastcgi_cache TEST; fastcgi_cache_valid 200 302 1h; fastcgi_cache_valid 301 1d; fastcgi_cache_valid any 1m;
上述代碼的含義:
第一行代碼是為FastCGI緩存指定一個文件路徑、目錄結構等級、關鍵字區域存儲時間和非活動刪除時間。
fastcgi_connect_timeout指定連接到后端FastCGI的超時時間。
fastcgi_send_timeout指定向FastCGI傳送請求的超時時間,這個值是已經完成兩次握手后向FastCGI傳送請求的超時時間。
fastcgi_read_timeout指定接收FastCGI應答的超時時間,這個值是已經完成兩次握手后接收FastCGI應答的超時時間。
fastcgi_buffer_size用於指定讀取FastCGI應答第一部分需要用多大的緩沖區,這個值表示將使用1個64KB的緩沖區讀取應答的第一部分(應答頭),可以設置為fastcgi_buffers選項指定的緩沖區大小。
fastcgi_buffers指定本地需要用多少和多大的緩沖區來緩沖FastCGI的應答請求。如果一個PHP腳本所產生的頁面大小為256KB,那么會為其分配4個64KB的緩沖區來緩存;如果頁面大小大於256KB,那么大於256KB的部分會緩存到fastcgi_temp指定的路徑中,但是這並不是好方法,因為內存中的數據處理速度要快於硬盤。一般這個值應該為站點中PHP腳本所產生的頁面大小的中間值,如果站點大部分腳本所產生的頁面大小為256KB,那么可以把這個值設置為“16 16k”、“4 64k”等。
fastcgi_busy_buffers_size的默認值是fastcgi_buffers的兩倍。
fastcgi_temp_file_write_size表示在寫入緩存文件時使用多大的數據塊,默認值是fastcgi_buffers的兩倍。
fastcgi_cache表示開啟FastCGI緩存並為其指定一個名稱。開啟緩存非常有用,可以有效降低CPU的負載,並且防止502錯誤的發生,但是開啟緩存也會引起很多問題,要視具體情況而定。
fastcgi_cache_valid、fastcgi用來指定應答代碼的緩存時間,實例中的值表示將200和302應答緩存一個小時,將301應答緩存1天,其他應答均緩存1分鍾。
參考鏈接:
https://www.cnblogs.com/skynet/p/4173450.html
https://www.cnblogs.com/yezhaohui/p/4377662.html