FastCgi與PHP-fpm之間是個什麼樣的關係

剛開始對這個問題我也挺糾結的,看了《HTTP權威指南》後,感覺清晰了不少。

首先,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程序性能的。

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

那PHP-FPM又是什麼呢?是一個實現了Fastcgi的程序,被PHP官方收了。

大家都知道,PHP的解釋器是php-cgi。php-cgi只是個CGI程序,他自己本身只能解析請求,返回結果,不會進程管理(皇上,臣妾 真的做不到啊!)所以就出現了一些能夠調度php-cgi進程的程序,比如說由lighthttpd分離出來的spawn-fcgi。好了PHP-FPM 也是這麼個東東,在長時間的發展後,逐漸得到了大家的認可(要知道,前幾年大家可是抱怨PHP-FPM穩定性太差的),也越來越流行。

好了,最後來回來你的問題。
網上有的說,fastcgi是一個協議,php-fpm實現了這個協議

對。

有的說,php-fpm是fastcgi進程的管理器,用來管理fastcgi進程的

對。php-fpm的管理對象是php-cgi。但不能說php-fpm是fastcgi進程的管理器,因爲前面說了fastcgi是個協議,似乎沒有這麼個進程存在,就算存在php-fpm也管理不了他(至少目前是)。  有的說,php-fpm是php內核的一個補丁

以前是對的。因爲最開始的時候php-fpm沒有包含在PHP內核裏面,要使用這個功能,需要找到與源碼版本相同的php-fpm對內核打補丁,然後再編譯。後來PHP內核集成了PHP-FPM之後就方便多了,使用--enalbe-fpm這個編譯參數即可。

有的說,修改了php.ini配置文件後,沒辦法平滑重啓,所以就誕生了php-fpm

是的,修改php.ini之後,php-cgi進程的確是沒辦法平滑重啓的。php-fpm對此的處理機制是新的worker用新的配置,已經存在的worker處理完手上的活就可以歇着了,通過這種機制來平滑過度。

還有的說PHP-CGI是PHP自帶的FastCGI管理器,那這樣的話幹嗎又弄個php-fpm出

不對。php-cgi只是解釋PHP腳本的程序而已。



  •                       

    很好的回答,但對@尹川最後的一個問題的解析有異議。 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應運而生。 參考鏈接:http://www.mike.org.cn/articles/what-is-cgi-fastcgi-php-fpm-spawn-fcgi/

我看了上面三位的答案,但我總覺得他們描述得還不夠貼切。

Fastcgi是CGI的升級版,一種語言無關的協議,用來溝通程序(如PHP, Python, Java)和Web服務器(Apache2, Nginx), 理論上任何語言編寫的程序都可以通過Fastcgi來提供Web服務。
Fastcgi的特點是會在一個進程中依次完成多個請求,以達到提高效率的目的,大多數Fastcgi實現都會維護一個進程池。

而PHP-fpm就是針對於PHP的,Fastcgi的一種實現,他負責管理一個進程池,來處理來自Web服務器的請求。目前,PHP-fpm是內置於PHP的。

但是PHP-fpm僅僅是個“PHP Fastcgi 進程管理器”, 它仍會調用PHP解釋器本身來處理請求,PHP解釋器(在Windows下)就是php-cgi.exe.


                               

CGI is an interface which tells the webserver how to pass data back and forth to and from an application. More specifically, it describes how request information is passed in environment variables (such as request type, remote IP address), how the reqeust body is passed in via standard input, and how the response is passed out via standard output.

FASTCGI:WEB服務器與處理程序之間通信的一種協議,是CGI的改進方案。

CGI程序反覆加載是CGI性能低下的主要原因,如果CGI程序保持在內存中並接受FastCGI進程管理器調度,則可以提供良好的性能、伸縮性、Fail-Over特性等。

FASTCGI是常駐型的CGI,它可以一直運行,在請求到達時,不會花費時間去fork一個進程來處理。

FastCGI是語言無關的、可伸縮架構的CGI開放擴展,將CGI解釋器進程保持在內存中,以此獲得較高的性能。

一般情況下,FastCGI的整個工作流程是這樣的:

1、Web Server啓動時載入FastCGI進程管理器(IIS ISAPI或Apache Module)

2、FastCGI進程管理器自身初始化,啓動多個CGI解釋器進程(可見多個php-cgi)並等待WebServer的連接。

3、當客戶端請求到達Web Server時,FastCGI進程管理器選擇並連接到一個CGI解釋器。 Web server將CGI環境變量和標準輸入發送到FastCGI子進程php-cgi。

4、FastCGI子進程完成處理後將標準輸出和錯誤信息從同一連接返回Web Server。當FastCGI子進程關閉連接時,請求便告處理完成。FastCGI子進程接着等待並處理來自FastCGI進程管理器(運行在Web Server中)的下一個連接。在CGI模式中,php-cgi在此便退出了。


                               

fastcgi 是 app  server 和web server 之間的通信協議。 正常架構 app server 是master,web server是client

php-fpm 帶兩個功能:1.實現了一個支持fastcgi協議的server程序 2. 進程管理器

有了php-fpm,就可以把php腳本變成 多進程模式採用fastcgi協議的app server,和web server進行通信


CGI => http://www.w3.org/CGI/
FastCGI => http://www.fastcgi.com/drupal/
FPM => FastCGI Process Manager(FastCGI進程管理器)


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章