天天看點

fastcgi php-cgi與php-fpm差別和之間的關系

關于FastCGI、php-cgi、php-fpm的差別是什麼,各自有什麼用途,以及互相間的關系是什麼,查閱相關資料,可謂是衆說紛纭,莫衷一是:

說法一:fastcgi是一個協定,php-fpm實作了這個協定;

說法二:php-fpm是FASTCGI程序的管理器,用來管理fastcgi程序的;

說法三:php-fpm是php核心的一個更新檔;

說法四:修改了php.ini配置檔案後,沒辦法平滑重新開機,是以就誕生了php-fpm;

說法五:php-cgi是php自帶的FASTCGI管理器;

......

筆者在學習PHP時也曾有過這個困惑,也曾翻閱了很多資料,最近在交流過過程中,發現很多夥伴還是無法弄其作用和之間的聯系,是以寫下此文,抛磚引玉。

首先要了解的是CGI

CGI是幹嘛的?通俗的講,CGI是為了保證Web Server傳遞過來的資料是标準格式的,友善CGI程式的編寫者

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再把結果傳回給浏覽器。

CGI是個協定,跟程序什麼的沒關系。那FastCGI又是什麼呢?

Fastcgi是CGI的更新版,一種語言無關的協定,FastCGI是用來提高CGI程式性能的(從字面意思來能好了解)

标準的CGI對每個請求都會執行這些步驟(不閑累啊!啟動程序很累的說!),是以處理每個時間的時間會比較長。這明顯不合理嘛!那麼FastCGI是怎麼做的呢?首先,FastCGI會先啟一個master,解析配置檔案,初始化執行環境,然後再啟動多個worker。當請求過來時,master會傳遞給一個worker,然後立即可以接受下一個請求。這樣就避免了重複的勞動,效率自然是高。而且當worker不夠用時,master可以根據配置預先啟動幾個worker等着;當然空閑worker太多時,也會停掉一些,這樣就提高了性能,也節約了資源。這就是"FastCGI"的對程序的管理(先姑且這麼說)

php-fpm是什麼?

是一個實作了FastCGI(協定)的程式

大家都知道,PHP的解釋器是php-cgi。php-cgi隻是個CGI程式,他自己本身隻能解析請求,傳回結果,不會管理程序,是以就出現了一些能夠排程php-cgi程序的程式,比如說由lighthttpd分離出來的spawn-fcgi。好了php-fpm也是這麼個東西,在長時間的發展後,逐漸得到了大家的認可,也越來越流行。

php-fpm的管理對象是php-cgi,但不能說php-fpm是FastCGI程序的管理器,因為前面說了FastCGI是個協定,似乎沒有這麼個程序存在,就算存在php-fpm也管理不了他(至少目前是)。他負責管理一個程序池,來處理來自Web伺服器的請求。

php-fpm是PHP核心的一個更新檔? 以前是正确的,因為最開始的時候php-fpm沒有包含在PHP核心裡面,要使用這個功能,需要找到與源碼版本相同的php-fpm對核心打更新檔,然後再編譯。後來PHP(5.3以後)核心內建了php-fpm,編譯時加上--enalbe-fpm這個參數即可。

對于php.ini檔案的修改,php-cgi程序是沒辦法平滑重新開機的,有了php-fpm後,就把平滑重新開機成為了一種可能,php-fpm對此的處理機制是新的worker用新的配置,已經存在的worker處理完手上的活就可以歇着了,通過這種機制來平滑過度的。