關於CGI、fastcgi、PHP-CGI、PHP-FPM的理解

文章整理自:https://segmentfault.com/q/1010000000256516

CGI

首先,CGI是幹嘛的?CGI是爲了保證web server傳遞過來的數據是標準格式的,方便CGI程序的編寫者。所以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再把結果返回給瀏覽器。

fastcgi

CGI是個協議,跟進程什麼的沒關係。那fastcgi又是什麼呢?Fastcgi是用來提高CGI程序性能的協議,也可以說是一種優化方案,注意是CGI程序,不是爲了提高CGI性能。

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

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在此便退出了。

php-cgi

php-cgi只是個CGI程序,專門用於PHP語言的解釋器,依賴CGI協議進行工作。

PHP-FPM

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

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