簡單瞭解下CGI、FastCGI和php-fpm的概念和區別和執行原理

OldBoy~發表於2017-12-19

什麼是CGI?

CGI(Common Gateway Interface),公共閘道器介面,它是Web伺服器與外部應用程式(CGI程式)之間傳遞資訊的介面標準。通過CGI介面,Web伺服器就能夠獲取客戶端提交的資訊,並轉交給伺服器端的CGI程式處理,最後返回結果給客戶端。
也就是說,CGI實際上是一個介面標準。我們通常所說的CGI是指CGI程式,即實現了CGI介面標準的程式。
只要某種語言具有標準輸入、輸出和環境變數,如perl、php、C等,就可以用來編寫CGI程式。

CGI程式的工作方式:
Web伺服器一般只處理靜態檔案請求(如 jpg、htm、html),如果碰到一個動態指令碼請求(如php),web伺服器主程式,就fork出一個新的程式來啟動CGI程式,也就是說將動態指令碼請求交給CGI程式來處理。啟動CGI程式需要一個過程,比如,讀取配置檔案,載入擴充套件等。CGI程式啟動後,就會解析動態指令碼,然後將結果返回給Web伺服器,最後Web伺服器再將結果返回給客戶端,剛才fork的程式也會隨之關閉。
這樣,每次使用者請求動態指令碼,Web伺服器都要重新fork一個新程式,去啟動CGI程式,由CGI程式來處理動態指令碼,處理完後程式隨之關閉。
這種工作方式的效率是非常低下的。

PHP 直譯器是否嵌入 Web 伺服器程式內部執行

後來,出現了一種比較高效的方式:Web伺服器內建模組。例如,apache的mod_php模組。將php直譯器做成模組,然後載入到apache伺服器中。
這樣,apache伺服器在啟動的時候,就會同時啟動php模組。當客戶端請求php檔案時,apache伺服器就不用再fork出一個新程式來啟動php直譯器,而是直接將php檔案交給執行中的php模組處理。顯然,這種方式下,效率會比較高。
由於在apache伺服器啟動時,才會讀取php的配置檔案,載入php模組,在apache的執行過程中。不會再重新讀取php的配置檔案。所以,每次我們修改了php的配置檔案後,必須重啟apache,新的php配置檔案才會生效。
mod_php 通過嵌入 PHP 直譯器到 Apache 程式中,只能與 Apache 配合使用,而 cgi 和 fast-cgi 以獨立的程式的形式出現,只要對應的Web伺服器實現 cgi 或者 fast-cgi 協議,就能夠處理 PHP 請求。mod_php 這種嵌入的方式最大的弊端就是記憶體佔用大,不論是否用到 PHP 直譯器都會將其載入到記憶體中,典型的就是處理CSS、JS之類的靜態檔案是完全沒有必要載入直譯器。

什麼是FastCGI?

FastCGI就像是一個常駐(long-live)型的CGI程式,它可以一直執行著。FastCGI程式也可以和Web伺服器分別部署在不同的主機上,它還可以接受來自其他Web伺服器的請求。
FastCGI也是語言無關的。其主要行為是將CGI直譯器程式保持在記憶體中並因此獲得高效的效能。眾所周知,CGI直譯器的反覆載入是CGI效能低下的主要原因。
FastCGI是一種程式管理工具,它可以在記憶體中管理CGI程式。
FastCGI程式管理器需要單獨啟動。啟動FastCGI後,會生成一個FastCGI主程式和多個子程式(子程式其實就是CGI直譯器程式)。
當客戶端請求Web伺服器上的動態指令碼時,Web伺服器會將動態指令碼通過TCP協議交給FastCGI主程式,FastCGI主程式根據情況,安排一個空閒的子程式來解析動態指令碼,處理完成後將結果返回給Web伺服器,Web伺服器再將結果返回給客戶端。該客戶端請求處理完畢後,FastCGI子程式並不會隨之關閉,而是繼續等待主程式安排工作任務。

FastCGI的重要特點:
1、FastCGI是HTTP伺服器和動態指令碼語言間通訊的介面或者工具。
2、FastCGI優點是把動態語言解析和HTTP伺服器分離開來。
3、Nginx、Apache、Lighttpd以及多數動態語言都支援FastCGI。
4、FastCGI介面方式採用C/S架構,分為客戶端(HTTP伺服器)和服務端(動態語言解析伺服器)。
5、PHP動態語言服務端可以啟動多個FastCGI的守護程式。
6、HTTP伺服器通過FastCGI客戶端和動態語言FastCGI服務端通訊。

原理圖及執行過程:

一、Web Server啟動時載入FastCGI程式管理器(Apache Module或IIS ISAPI等)
二、FastCGI程式管理器自身初始化,啟動多個CGI直譯器程式(可建多個php-cgi),並等待來自Web Server的連線。
三、當客戶端請求到達Web Server時,FastCGI程式管理器選擇並連線到一個CGI直譯器。Web server將CGI環境變數和標準輸入傳送到FastCGI子程式php-cgi。
四、FastCGI子程式完成處理後,將標準輸出和錯誤資訊從同一連線返回Web Server。當FastCGI子程式關閉連線時,請求便告處理完成。FastCGI子程式接著等待,並處理來自FastCGI程式管理器(執行在Web Server中)的下一個連線。 在CGI模式中,php-cgi在此便退出了

什麼是php-fpm?

fpm是FastCGI Process Manager的縮寫,那麼,fpm就是FastCGI程式管理器的簡稱。

php-fpm就是php中的FastCGI程式管理器。
對於php5.3之前的版本來說,php-fpm是一個第三方的補丁包,旨在將FastCGI程式管理整合進PHP包中。
在php5.3之後的版本中,php-fpm不再是第三方的包,它已經被整合到php的原始碼中了。php-fpm提供了更好的PHP程式管理方式,可以有效控制記憶體和程式、可以平滑過載PHP配置,比spawn-fcgi具有更多優點,所以php-fpm被PHP官方收購了。

php-fpm的管理物件是php-cgi。但不能說php-fpm是fastcgi程式的管理器,因為前面說了fastcgi是個協議,似乎沒有這麼個程式存在,就算存在php-fpm也管理不了他(至少目前是)。 有的說,php-fpm是php核心的一個補丁以前是對的。因為最開始的時候php-fpm沒有包含在PHP核心裡面,要使用這個功能,需要找到與原始碼版本相同的php-fpm對核心打補丁,然後再編譯。後來PHP核心整合了PHP-FPM之後就方便多了,使用--enalbe-fpm這個編譯引數即可。

相關文章