萬盛學電腦網

 萬盛學電腦網 >> 網絡編程 >> php編程 >> 關於CGI 和 PHP

關於CGI 和 PHP

關於CGI 和 PHP-FPM我相信大家用會用但它們到底怎麼區別及哪裡不一樣可能不知道了,這裡為各位整理一篇關於CGI 和 PHP-FPM的對比分析文章。

首先我們引入一些概念,搞清楚 CGI 和 FastCGI

CGI

通用網關接口(Common Gateway Interface/CGI)是一種重要的互聯網技術,可以讓一個客戶端,從網頁浏覽器向執行在網絡服務器上的程序請求數據。CGI描述了服務器和請求處理程序之間傳輸數據的一種標准。
FastCGI

快速通用網關接口(Fast Common Gateway Interface/FastCGI)是一種讓交互程序與Web服務器通信的協議。FastCGI是早期通用網關接口(CGI)的增強版本。

FastCGI致力於減少網頁服務器與CGI程序之間互動的開銷,從而使服務器可以同時處理更多的網頁請求。
好現在明白了

CGI 和 FastCGI 是一種通信協議規范,不是一個實體
我們平常需要用詞規范,是CGI 還是 CGI程序

CGI 程序和FastCGI程序,是指實現這兩個協議的程序,可以是任何語言實現這個協議的。(PHP-CGI 和 PHP-FPM就是實現FastCGI的程序)


為什麼推薦使用FastCGI程序

除了上面對兩個協議的描述外,這裡再補充下他們實現的程序的區別。

關於CGI程序

CGI使外部程序與Web服務器之間交互成為可能。CGI程序運行在獨立的進程中,並對每個Web請求建立一個進程,這種方法非常容易實現,但效率很差,難以擴展。面對大量請求,進程的大量建立和消亡使操作系統性能大大下降。此外,由於地址空間無法共享,也限制了資源重用。
關於FastCGI程序

與為每個請求創建一個新的進程不同,FastCGI使用持續的進程來處理一連串的請求。這些進程由FastCGI服務器管理,而不是web服務器。 當進來一個請求時,web服務器把環境變量和這個頁面請求通過一個socket比如FastCGI進程與web服務器(都位於本地)或者一個TCP connection(FastCGI進程在遠端的server farm)傳遞給FastCGI進程。
FastCGI為了提高CGI的效率而存在的。

PHP-CGI 和 PHP-FPM的區別


PHP-CGI是PHP自帶的FastCGI管理器。啟動PHP-CGI,使用如下命令:

php-cgi -b 127.0.0.1:9000

php-cgi與php-fpm一樣,也是一個fastcgi進程管理器,php-cgi的問題在於 1、php-cgi變更php.ini配置後需重啟php-cgi才能讓新的php-ini生效,不可以平滑重啟 2、直接殺死php-cgi進程,php就不能運行了。(PHP-FPM和Spawn-FCGI就沒有這個問題,守護進程會平滑從新生成新的子進程。) 針對php-cgi的不足,php-fpm應運而生。

PHP-FPM 的管理對象是php-cgi。使用PHP-FPM來控制PHP-CGI的FastCGI進程

Nginx 如何調用PHP

web server(比如說nginx)只是內容的分發者。比如,如果請求/index.html,那麼web server會去文件系統中找到這個文件,發送給浏覽器,這裡分發的是靜態數據。好了,如果現在請求的是/index.php,根據配置文件,nginx知道這個不是靜態文件,需要去找PHP解析器來處理,那麼他會把這個請求簡單處理後交給PHP解析器。Nginx會傳哪些數據給PHP解析器呢?url要有吧,查詢字符串也得有吧,POST數據也要有,HTTP header不能少吧,好的,CGI就是規定要傳哪些數據、以什麼樣的格式傳遞給後方處理這個請求的協議。仔細想想,你在PHP代碼中使用的用戶從哪裡來的。

當web server收到/index.php這個請求後,會啟動對應的CGI程序,這裡就是PHP的解析器。接下來PHP解析器會解析php.ini文件,初始化執行環境,然後處理請求,再以規定CGI規定的格式返回處理後的結果,退出進程。web server再把結果返回給浏覽器。

Apache如何調用PHP

Apache 有個mod_php 擴展。php是apache的一個外掛程序,必須依靠web服務器才可以運行。當客戶端浏覽器觸發事件--->url 提交到apache服務器---->apache服務器根據php程序的特點判斷是php程序,提交給php引擎程序--->php引擎程序解析並讀取數據庫生成相應的頁面

FastCGI運行模式分析:

FastCGI的工作原理是:

(1)、Web Server 啟動時載入FastCGI進程管理器【PHP的FastCGI進程管理器是PHP-FPM(php-FastCGI Process Manager)】(IIS ISAPI或Apache Module);
(2)、FastCGI進程管理器自身初始化,啟動多個CGI解釋器進程 (在任務管理器中可見多個php-cgi.exe)並等待來自Web Server的連接。
(3)、當客戶端請求到達Web Server時,FastCGI進程管理器選擇並連接到一個CGI解釋器。Web server將CGI環境變量和標准輸入發送到FastCGI子進程php-cgi.exe。
(4)、FastCGI子進程完成處理後將標准輸出和錯誤信息從同一連接返回Web Server。當FastCGI子進程關閉連接時,請求便告處理完成。FastCGI子進程接著等待並處理來自FastCGI進程管理器(運行在 WebServer中)的下一個連接。 在正常的CGI模式中,php-cgi.exe在此便退出了。

在上述情況中,你可以想象 CGI通常有多慢。每一個Web請求PHP都必須重新解析php.ini、重新載入全部dll擴展並重初始化全部數據結構。使用FastCGI,所有這些 都只在進程啟動時發生一次。一個額外的好處是,持續數據庫連接(Persistent database connection)可以工作。

 為什麼要使用FastCGI,而不是多線程CGI解釋器?
這可能出於多方面的考慮,例如:

(1)、你無論如何也不能在windows平台上穩定的使用多線程CGI解釋器,無論是IIS ISAPI方式還是APACHE Module方式,它們總是運行一段時間就崩潰了。奇怪麼?但是確實存在這樣的情況!
當然,也有很多時候你能夠穩定的使用多線程CGI解釋器,但是,你有可能發現網頁有時候會出現錯誤,無論如何也找不到原因,而換用FastCGI方式 時這種錯誤的概率會大大的降低。我也不清楚這是為什麼,我想獨立地址空間的CGI解釋器可能終究比共享地址空間的形式來得穩定一點點。
(2)、性能!性能?可能麼,難道FastCGI比多線程CGI解釋器更快?但有時候確實是這樣,只有測試一下你的網站,才能最後下結論。原因嘛,我覺得 很難講,但有資料說在Zend WinEnabler的時代,Zend原來也是建議在Windows平台下使用FastCGI而不是IIS ISAPI或Apache Module,不過現在Zend已經不做這個產品了。

 FastCGI 模式運行PHP 的優點:

以 FastCGI 模式運行 PHP 有幾個主要的好處。首先就是 PHP 出錯的時候不會搞垮 Apache,只是 PHP 自己的進程當掉(但 FastCGI 會立即重新啟動一個新 PHP 進程來代替當掉的進程)。其次 FastCGI 模式運行 PHP 比 ISAPI 模式性能更好(我本來用 ApacheBench 進行了測試,但忘了保存結果,大家有興趣可以自己測試)。

copyright © 萬盛學電腦網 all rights reserved