PHP-FPM、CGI、FastCGI以及Nginx運行PHP的原理簡述

幾點明悟:php

(1)Nginx和PHP能夠分別安裝在不一樣機器上:由於Nginx與PHP是隔離開的,Nginx只是將請求轉發給PHP引擎html

(2)Apache和PHP必須安裝在同一臺機器上:由於Apache將PHP做爲本身的程序模塊來運行,PHP成爲了Apache程序的一部分web

 

什麼是CGI?apache

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 服務器進程內部執行php-fpm

後來,出現了一種比較高效的方式: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?post

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的重要特色:
一、FastCGI是HTTP服務器和動態腳本語言間通訊的接口或者工具。
二、FastCGI優勢是把動態語言解析和HTTP服務器分離開來。
三、Nginx、Apache、Lighttpd以及多數動態語言都支持FastCGI。
四、FastCGI接口方式採用C/S架構,分爲客戶端(HTTP服務器)和服務端(動態語言解析服務器)。
五、PHP動態語言服務端能夠啓動多個FastCGI的守護進程。
六、HTTP服務器經過FastCGI客戶端和動態語言FastCGI服務端通訊。

原理圖及運行過程:

(1)Web Server啓動時載入FastCGI進程管理器(Apache Module或IIS ISAPI等)
(2)FastCGI進程管理器自身初始化,啓動多個CGI解釋器進程(可建多個php-cgi),並等待來自Web Server的鏈接。
(3)當客戶端請求到達Web Server時,FastCGI進程管理器選擇並鏈接到一個CGI解釋器。Web server將CGI環境變量和標準輸入發送到FastCGI子進程php-cgi。
(4)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這個編譯參數便可。

相關文章
相關標籤/搜索