什麼是CGI、FastCGI、PHP-CGI、PHP-FPM、Spawn-FCGI?


CGI

CGI即通用網關接口(Common Gateway Interface),是外部應用程序(CGI程序)與Web服務器之間的接口標準,是在CGI程序和Web服務器之間傳遞信息的規程。CGI規範允許Web服務器執行外部程序,並將它們的輸出發送給Web瀏覽器,CGI將Web的一組簡單的靜態超媒體文檔變成一個完整的新的交互式媒體。通俗的講CGI就像是一座橋,把網頁和WEB服務器中的執行程序連接起來,它把HTML接收的指令傳遞給服務器的執行程序,再把服務器執行程序的結果返還給HTML頁。CGI 的跨平臺性能極佳,幾乎可以在任何操作系統上實現。

CGI方式在遇到連接請求(用戶請求)先要創建cgi的子進程,激活一個CGI進程,然後處理請求,處理完後結束這個子進程。這就是fork-and-execute模式。所以用cgi方式的服務器有多少連接請求就會有多少cgi子進程,子進程反覆加載是cgi性能低下的主要原因。當用戶請求數量非常多時,會大量擠佔系統的資源如內存,CPU時間等,造成效能低下。

CGI腳本工作流程:

  1. 瀏覽器通過HTML表單或超鏈接請求指向一個CGI應用程序的URL。
  2. 服務器收發到請求。
  3. 服務器執行所指定的CGI應用程序。
  4. CGI應用程序執行所需要的操作,通常是基於瀏覽者輸入的內容。
  5. CGI應用程序把結果格式化爲網絡服務器和瀏覽器能夠理解的文檔(通常是HTML網頁)。
  6. 網絡服務器把結果返回到瀏覽器中。

FastCGI

FastCGI是一個可伸縮地、高速地在HTTP server和動態腳本語言間通信的接口。多數流行的HTTP server都支持FastCGI,包括Apache、Nginx和lighttpd等,同時,FastCGI也被許多腳本語言所支持,其中就有PHP。

FastCGI是從CGI發展改進而來的。傳統CGI接口方式的主要缺點是性能很差,因爲每次HTTP服務器遇到動態程序時都需要重新啓動腳本解析器來執行解析,然後結果被返回給HTTP服務器。這在處理高併發訪問時,幾乎是不可用的。FastCGI像是一個常駐(long-live)型的CGI,它可以一直執行着,只要激活後,不會每次都要花費時間去fork一次(這是CGI最爲人詬病的fork-and-execute 模式)。CGI 就是所謂的短生存期應用程序,FastCGI 就是所謂的長生存期應用程序。由於 FastCGI 程序並不需要不斷的產生新進程,可以大大降低服務器的壓力並且產生較高的應用效率。它的速度效率最少要比CGI 技術提高 5 倍以上。它還支持分佈式的運算, 即 FastCGI 程序可以在網站服務器以外的主機上執行並且接受來自其它網站服務器來的請求。

FastCGI是語言無關的、可伸縮架構的CGI開放擴展,其主要行爲是將CGI解釋器進程保持在內存中並因此獲得較高的性能。衆所周知,CGI解釋器的反覆加載是CGI性能低下的主要原因,如果CGI解釋器保持在內存中並接受FastCGI進程管理器調度,則可以提供良好的性能、伸縮性、Fail-Over特性等等。FastCGI接口方式採用C/S結構,可以將HTTP服務器和腳本解析服務器分開,同時在腳本解析服務器上啓動一個或者多個腳本解析守護進程。當HTTP服務器每次遇到動態程序時,可以將其直接交付給FastCGI進程來執行,然後將得到的結果返回給瀏覽器。這種方式可以讓HTTP服務器專一地處理靜態請求或者將動態腳本服務器的結果返回給客戶端,這在很大程度上提高了整個應用系統的性能。

FastCGI的工作流程:

  1. Web Server啓動時載入FastCGI進程管理器(PHP-CGI或者PHP-FPM或者spawn-cgi)
  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在此便退出。

FastCGI 的特點

  1. 打破傳統頁面處理技術。傳統的頁面處理技術,程序必須與 Web 服務器或 Application 服務器處於同一臺服務器中。這種歷史已經早N年被FastCGI技術所打破,FastCGI技術的應用程序可以被安裝在服務器羣中的任何一臺服務器,而通過 TCP/IP 協議與 Web 服務器通訊,這樣做既適合開發大型分佈式 Web 羣,也適合高效數據庫控制。
  2. 明確的請求模式。CGI 技術沒有一個明確的角色,在 FastCGI 程序中,程序被賦予明確的角色(響應器角色、認證器角色、過濾器角色)。

ISAPI

ISAPI(Internet Server Application Program Interface)是微軟提供的一套面向WEB服務的API接口,它能實現CGI提供的全部功能,並在此基礎上進行了擴展,如提供了過濾器應用程序接口。ISAPI應用大多數以DLL動態庫的形式使用,可以在被用戶請求後執行,在處理完一個用戶請求後不會馬上消失,而是繼續駐留在內存中等待處理別的用戶輸入。此外,ISAPI的DLL應用程序和WEB服務器處於同一個進程中,效率要顯著高於CGI。(由於微軟的排他性,只能運行於windows環境)

ISAPI服務器擴展爲使用 Internet 服務器的通用網關接口(CGI) 應用程序提供了另一種選擇。與 CGI 應用程序不同,ISA 在 HTTP服務器所在的同一地址空間運行,並且可以訪問可由 HTTP 服務器使用的所有資源。ISA 的系統開銷比 CGI 應用程序低,因爲它們不要求創建其他進程,也不執行需要越過進程邊界的通信,而這種通信非常耗時。如果內存被其他進程所需要,擴展和篩選器DLL 都可能被卸載。ISAPI 允許在一個 DLL 中有多個命令,這些命令作爲 DLL 中CHttpServer對象的成員函數來實現。CGI 要求每個任務有一個單獨的名稱和一個到單獨的可執行文件的 URL 映射。每個新的 CGI 請求啓動一個新進程,而每個不同的請求包含在各自的可執行文件中,這些文件根據每個請求加載和卸載,因此係統開銷高於 ISA。

PHP-CGI

PHP-CGI是PHP自帶的FastCGI管理器。PHP-CGI的不足:

  1. php-cgi變更php.ini配置後需重啓php-cgi才能讓新的php-ini生效,不可以平滑重啓
  2. 直接殺死php-cgi進程php就不能運行了。(PHP-FPM和Spawn-FCGI就沒有這個問題,守護進程會平滑從新生成新的子進程。)

Spawn-FCGI

Spawn-FCGI是一個通用的FastCGI管理服務器,它是lighttpd中的一部份,很多人都用Lighttpd的Spawn-FCGI進行FastCGI模式下的管理工作,不過有不少缺點。而PHP-FPM的出現多少緩解了一些問題,但PHP-FPM有個缺點就是要重新編譯,這對於一些已經運行的環境可能有不小的風險),在php 5.3.3中可以直接使用PHP-FPM了。Spawn-FCGI的代碼很少,全部才630行,用c語言編寫,最近一次提交是5年前。代碼主頁:https://github.com/lighttpd/spawn-fcgi

Spawn-FCGI代碼分析如下:

  1. spawn-fcgi 首先create socket,bind,listen 3步創建服務器socket,(把這個socket叫做 fcgi_fd)
  2. 用dup2,把fcgi_fd 交換給 FCGI_LISTENSOCK_FILENO (FCGI_LISTENSOCK_FILENO數值上等於0,這是fastcgi協議當中指定用來listen的socket id)
  3. 執行execl ,replaces the current process image with a new process image. process image 進程在運行空間的代碼段

很顯然,Spawn-FCGI也是 pre-fork 模型,只是用了上古C語言編寫,充滿了N多 unix下暗黑編程技巧。

Spawn-FCGI功能很單一:

  1. 只管fork進程,子進程掛了,主進程僅僅log記錄一次,根本不會重新fork。在2009年一段時間內,我曾經用spawn-fcgi部署php-cgi,當跑一段時間就會全掛掉,只能用crontab定時重啓spawn-fcgi
  2. 不負責子進程中的網絡IO,把socket放到指定位置就完了,接下來的事情由被spawn的程序處理

Spawn-FCGI是一個很早期的程序,瞻仰一下即可。另外有:1996年的一段代碼:http://www.fastcgi.com/om_archive/kit/cgi-fcgi/cgi-fcgi.c,和spawn-fcgi一個風格

PHP-FPM

PHP-FPM是一個PHP FastCGI管理器,是隻用於PHP的,可以在 http://php-fpm.org/download下載得到。PHP-FPM其實是PHP源代碼的一個補丁,旨在將FastCGI進程管理整合進PHP包中。必須將它patch到你的PHP源代碼中,在編譯安裝PHP後纔可以使用。FPM(FastCGI 進程管理器)用於替換 PHP-CGI 的大部分附加功能,對於高負載網站是非常有用的。它的功能包括:

  1. 支持平滑停止/啓動的高級進程管理功能;
  2. 可以工作於不同的 uid/gid/chroot 環境下,並監聽不同的端口和使用不同的 php.ini 配置文件(可取代 safe_mode 的設置);
  3. stdout 和 stderr 日誌記錄;
  4. 在發生意外情況的時候能夠重新啓動並緩存被破壞的 opcode;
  5. 文件上傳優化支持;
  6. “慢日誌” – 記錄腳本(不僅記錄文件名,還記錄 PHP backtrace 信息,可以使用 ptrace或者類似工具讀取和分析遠程進程的運行數據)運行所導致的異常緩慢;
  7. fastcgi_finish_request() – 特殊功能:用於在請求完成和刷新數據後,繼續在後臺執行耗時的工作(錄入視頻轉換、統計處理等);
  8. 動態/靜態子進程產生;
  9. 基本 SAPI 運行狀態信息(類似Apache的 mod_status);
  10. 基於 php.ini 的配置文件。

WSGI

Web服務器網關接口(Python Web Server Gateway Interface,縮寫爲WSGI)是爲Python語言定義的Web服務器和Web應用程序或框架之間的一種簡單而通用的接口。自從WSGI被開發出來以後,許多其它語言中也出現了類似接口。WSGI是作爲Web服務器與Web應用程序或應用框架之間的一種低級別的接口,以提升可移植Web應用開發的共同點。WSGI是基於現存的CGI標準而設計的。

WSGI區分爲兩個部份:一爲“服務器”或“網關”,另一爲“應用程序”或“應用框架”。在處理一個WSGI請求時,服務器會爲應用程序提供環境資訊及一個回呼函數(Callback Function)。當應用程序完成處理請求後,透過前述的回呼函數,將結果回傳給服務器。所謂的 WSGI 中間件同時實現了API的兩方,因此可以在WSGI服務和WSGI應用之間起調解作用:從WSGI服務器的角度來說,中間件扮演應用程序,而從應用程序的角度來說,中間件扮演服務器。“中間件”組件可以執行以下功能:

  1. 重寫環境變量後,根據目標URL,將請求消息路由到不同的應用對象。
  2. 允許在一個進程中同時運行多個應用程序或應用框架。
  3. 負載均衡和遠程處理,通過在網絡上轉發請求和響應消息。
  4. 進行內容後處理,例如應用XSLT樣式表。

以前,如何選擇合適的Web應用程序框架成爲困擾Python初學者的一個問題,這是因爲,一般而言,Web應用框架的選擇將限制可用的Web服務器的選擇,反之亦然。那時的Python應用程序通常是爲CGI,FastCGI,mod_python中的一個而設計,甚至是爲特定Web服務器的自定義的API接口而設計的。WSGI沒有官方的實現, 因爲WSGI更像一個協議。只要遵照這些協議,WSGI應用(Application)都可以在任何服務器(Server)上運行, 反之亦然。WSGI就是Python的CGI包裝,相對於Fastcgi是PHP的CGI包裝。

WSGI將 web 組件分爲三類: web服務器,web中間件,web應用程序, wsgi基本處理模式爲 : WSGI Server -> (WSGI Middleware)* -> WSGI Application 。

wsgi

1、WSGI Server/gateway

wsgi server可以理解爲一個符合wsgi規範的web server,接收request請求,封裝一系列環境變量,按照wsgi規範調用註冊的wsgi app,最後將response返回給客戶端。文字很難解釋清楚wsgi server到底是什麼東西,以及做些什麼事情,最直觀的方式還是看wsgi server的實現代碼。以python自帶的wsgiref爲例,wsgiref是按照wsgi規範實現的一個簡單wsgi server。它的代碼也不復雜。

wsgi-gateway

  1. 服務器創建socket,監聽端口,等待客戶端連接。
  2. 當有請求來時,服務器解析客戶端信息放到環境變量environ中,並調用綁定的handler來處理請求。
  3. handler解析這個http請求,將請求信息例如method,path等放到environ中。
  4. wsgi handler再將一些服務器端信息也放到environ中,最後服務器信息,客戶端信息,本次請求信息全部都保存到了環境變量environ中。
  5. wsgi handler 調用註冊的wsgi app,並將environ和回調函數傳給wsgi app
  6. wsgi app 將reponse header/status/body 回傳給wsgi handler
  7. 最終handler還是通過socket將response信息塞回給客戶端。

2、WSGI Application

wsgi application就是一個普通的callable對象,當有請求到來時,wsgi server會調用這個wsgi app。這個對象接收兩個參數,通常爲environ,start_response。environ就像前面介紹的,可以理解爲環境變量,跟一次請求相關的所有信息都保存在了這個環境變量中,包括服務器信息,客戶端信息,請求信息。start_response是一個callback函數,wsgi application通過調用start_response,將response headers/status 返回給wsgi server。此外這個wsgi app會return 一個iterator對象 ,這個iterator就是response body。這麼空講感覺很虛,對着下面這個簡單的例子看就明白很多了。

3、WSGI MiddleWare

有些功能可能介於服務器程序和應用程序之間,例如,服務器拿到了客戶端請求的URL, 不同的URL需要交由不同的函數處理,這個功能叫做 URL Routing,這個功能就可以放在二者中間實現,這個中間層就是 middleware。middleware對服務器程序和應用是透明的,也就是說,服務器程序以爲它就是應用程序,而應用程序以爲它就是服務器。這就告訴我們,middleware需要把自己僞裝成一個服務器,接受應用程序,調用它,同時middleware還需要把自己僞裝成一個應用程序,傳給服務器程序。

其實無論是服務器程序,middleware 還是應用程序,都在服務端,爲客戶端提供服務,之所以把他們抽象成不同層,就是爲了控制複雜度,使得每一次都不太複雜,各司其職。

參考資料:

uWCGI

uWSGI 項目旨在爲部署分佈式集羣的網絡應用開發一套完整的解決方案。uWSGI主要面向web及其標準服務,已經成功的應用於多種不同的語言。由於uWSGI的可擴展架構,它能夠被無限制的擴展用來支持更多的平臺和語言。目前,你可以使用C,C++和Objective-C來編寫插件。項目名稱中的“WSGI”是爲了向同名的Python Web標準表示感謝,因爲WSGI爲該項目開發了第一個插件。uWSGI是一個Web服務器,它實現了WSGI協議、uwsgi、http等協議。uWSGI,既不用wsgi協議也不用FastCGI協議,而是自創了一個uwsgi的協議,uwsgi協議是一個uWSGI服務器自有的協議,它用於定義傳輸信息的類型(type of information),每一個uwsgi packet前4byte爲傳輸信息類型描述,它與WSGI相比是兩樣東西。據說該協議大約是fcgi協議的10倍那麼快。

uWSGI的主要特點如下:

  1. 超快的性能。
  2. 低內存佔用(實測爲apache2的mod_wsgi的一半左右)。
  3. 多app管理。
  4. 詳盡的日誌功能(可以用來分析app性能和瓶頸)。
  5. 高度可定製(內存大小限制,服務一定次數後重啓等)。

其他拓展知識:Java Servlet、Sinatra、Rack



#-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

  什麼是CGI

  CGI全稱是“公共網關接口”(Common Gateway Interface),HTTP服務器與你的或其它機器上的程序進行“交談”的一種工具,其程序須運行在網絡服務器上。

  CGI可以用任何一種語言編寫,只要這種語言具有標準輸入、輸出和環境變量。如php,perl,tcl等

  什麼是FastCGI

  FastCGI像是一個常駐(long-live)型的CGI,它可以一直執行着,只要激活後,不會每次都要花費時間去fork一次(這是CGI最爲人詬病的fork-and-execute 模式)。它還支持分佈式的運算, 即 FastCGI 程序可以在網站服務器以外的主機上執行並且接受來自其它網站服務器來的請求。

  FastCGI是語言無關的、可伸縮架構的CGI開放擴展,其主要行爲是將CGI解釋器進程保持在內存中並因此獲得較高的性能。衆所周知,CGI解釋器的反覆加載是CGI性能低下的主要原因,如果CGI解釋器保持在內存中並接受FastCGI進程管理器調度,則可以提供良好的性能、伸縮性、Fail- Over特性等等。

  FastCGI與CGI特點

  1、如CGI,FastCGI也具有語言無關性.

  2、如CGI, FastCGI在進程中的應用程序,獨立於核心web服務器運行,提供了一個比API更安全的環境。(APIs把應用程序的代碼與核心的web服務器鏈接在一起,這意味着在一個錯誤的API的應用程序可能會損壞其他應用程序或核心服務器; 惡意的API的應用程序代碼甚至可以竊取另一個應用程序或核心服務器的密鑰。)

  3、FastCGI技術目前支持語言有:C/C++、Java、Perl、Tcl、Python、SmallTalk、Ruby等。相關模塊在Apache, ISS, Lighttpd等流行的服務器上也是可用的。

  4、如CGI,FastCGI的不依賴於任何Web服務器的內部架構,因此即使服務器技術的變化, FastCGI依然穩定不變。

  FastCGI的工作原理
  
  1、Web Server啓動時載入FastCGI進程管理器(IIS ISAPI或Apache Module)
  
  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在此便退出了。
  
  在上述情況中,你可以想象CGI通常有多慢。每一個Web請求PHP都必須重新解析php.ini、重新載入全部擴展並重初始化全部數據結構。使用FastCGI,所有這些都只在進程啓動時發生一次。一個額外的好處是,持續數據庫連接(Persistent database connection)可以工作。

  FastCGI的不足

  因爲是多進程,所以比CGI多線程消耗更多的服務器內存,PHP-CGI解釋器每進程消耗7至25兆內存,將這個數字乘以50或100就是很大的內存數。
  
  Nginx 0.8.46+PHP 5.2.14(FastCGI)服務器在3萬併發連接下,開啓的10個Nginx進程消耗150M內存(15M*10=150M),開啓的64個php-cgi進程消耗1280M內存(20M*64=1280M),加上系統自身消耗的內存,總共消耗不到2GB內存。如果服務器內存較小,完全可以只開啓25個php-cgi進程,這樣php-cgi消耗的總內存數才500M。

  上面的數據摘自Nginx 0.8.x + PHP 5.2.13(FastCGI)搭建勝過Apache十倍的Web服務器(第6版)

  什麼是PHP-CGI

  PHP-CGI是PHP自帶的FastCGI管理器。

  啓動PHP-CGI,使用如下命令:

php-cgi -b 127.0.0.1:9000

  PHP-CGI的不足

  1、php-cgi變更php.ini配置後需重啓php-cgi才能讓新的php-ini生效,不可以平滑重啓

  2、直接殺死php-cgi進程,php就不能運行了。(PHP-FPM和Spawn-FCGI就沒有這個問題,守護進程會平滑從新生成新的子進程。)

  什麼是PHP-FPM

  PHP-FPM是一個PHP FastCGI管理器,是隻用於PHP的,可以在 http://php-fpm.org/download下載得到.

  PHP-FPM其實是PHP源代碼的一個補丁,旨在將FastCGI進程管理整合進PHP包中。必須將它patch到你的PHP源代碼中,在編譯安裝PHP後纔可以使用。

  現在我們可以在最新的PHP 5.3.2的源碼樹裏下載得到直接整合了PHP-FPM的分支,據說下個版本會融合進PHP的主分支去。相對Spawn-FCGI,PHP-FPM在CPU和內存方面的控制都更勝一籌,而且前者很容易崩潰,必須用crontab進行監控,而PHP-FPM則沒有這種煩惱。

  PHP5.3.3已經集成php-fpm了,不再是第三方的包了。PHP-FPM提供了更好的PHP進程管理方式,可以有效控制內存和進程、可以平滑重載PHP配置,比spawn-fcgi具有更多有點,所以被PHP官方收錄了。在./configure的時候帶 –enable-fpm參數即可開啓PHP-FPM。

  使用PHP-FPM來控制PHP-CGI的FastCGI進程

/usr/local/php/sbin/php-fpm{start|stop|quit|restart|reload|logrotate}

--start 啓動php的fastcgi進程
--stop 強制終止php的fastcgi進程
--quit 平滑終止php的fastcgi進程
--restart 重啓php的fastcgi進程
--reload 重新平滑加載php的php.ini
--logrotate 重新啓用log文件 

  什麼是Spawn-FCGI

  Spawn-FCGI是一個通用的FastCGI管理服務器,它是lighttpd中的一部份,很多人都用Lighttpd的Spawn-FCGI進行FastCGI模式下的管理工作,不過有不少缺點。而PHP-FPM的出現多少緩解了一些問題,但PHP-FPM有個缺點就是要重新編譯,這對於一些已經運行的環境可能有不小的風險(refer),在php 5.3.3中可以直接使用PHP-FPM了。

  Spawn-FCGI目前已經獨成爲一個項目,更加穩定一些,也給很多Web 站點的配置帶來便利。已經有不少站點將它與nginx搭配來解決動態網頁。

  最新的lighttpd也沒有包含這一塊了(http://www.lighttpd.net/search?q=Spawn-FCGI),但可以在以前版本中找到它。在lighttpd-1.4.15版本中就包含了(http://www.lighttpd.net/download/lighttpd-1.4.15.tar.gz)

  目前Spawn-FCGI的下載地址是http://redmine.lighttpd.net/projects/spawn-fcgi,最新版本是http://www.lighttpd.net/download/spawn-fcgi-1.6.3.tar.gz

  注:最新的Spawn-FCGI可以到lighttpd.net網站搜索“Spawn-FCGI”找到它的最新版本發佈地址

  下面我們就可以使用Spawn-FCGI來控制php-CGI的FastCGI進程了

    /usr/local/bin/spawn-fcgi -a 127.0.0.1 -p 9000 -C 5 -u www-data -g www-data -f /usr/bin/php-CGI

  參數含義如下:

  -f 指定調用FastCGI的進程的執行程序位置,根據系統上所裝的PHP的情況具體設置
  -a 綁定到地址addr
  -p 綁定到端口port
  -s 綁定到unix socket的路徑path
  -C 指定產生的FastCGI的進程數,默認爲5(僅用於PHP)
  -P 指定產生的進程的PID文件路徑
  -u和-g FastCGI使用什麼身份(-u 用戶 -g 用戶組)運行,Ubuntu下可以使用www-data,其他的根據情況配置,如nobody、apache等

  PHP-FPM與spawn-CGI對比測試

  PHP-FPM的使用非常方便,配置都是在PHP-FPM.ini的文件內,而啓動、重啓都可以從php/sbin/PHP-FPM中進行。更方便的是修改php.ini後可以直接使用PHP-FPM reload進行加載,無需殺掉進程就可以完成php.ini的修改加載
結果顯示使用PHP-FPM可以使php有不小的性能提升。PHP-FPM控制的進程cpu回收的速度比較慢,內存分配的很均勻。

  Spawn-FCGI控制的進程CPU下降的很快,而內存分配的比較不均勻。有很多進程似乎未分配到,而另外一些卻佔用很高。可能是由於進程任務分配的不均勻導致的.而這也導致了總體響應速度的下降。而PHP-FPM合理的分配,導致總體響應的提到以及任務的平均。

  PHP-FPM與Spawn-FCGI功能比較

  http://php-fpm.org/about/

  PHP-FPM、Spawn-FCGI都是守護php-cgi的進程管理器。

  參考文檔:

  http://topic.csdn.net/u/20100216/22/5809e272-6f67-4248-bde9-99deeae5215b.html
  http://topic.csdn.net/u/20101015/19/8ae74452-ec6b-448e-9942-21faeb008cd7.html
  http://club.topsage.com/thread-768488-1-1.html
  http://www.unixaid.info/index.php/productsapp/23-servsf/842-spawn-fcgi
  http://www.fastcgi.com/drupal/node/2
  http://baike.baidu.com/view/641394.htm
  http://baike.baidu.com/view/32614.htm
  http://blog.yation.com/network/fastcgi/


#-------------------------------------------------------------------------------------------------------------------------------------------------------

CGI 的作用

CGI 是爲了保證 web server 傳遞過來的數據是標準格式的,方便 CGI 程序的編寫者。
web server(比如說 nginx)只是內容的分發者。
如果請求 /index.html,那麼 web server 會去文件系統中找到這個文件,發送給瀏覽器,這裏分發的是靜態數據。
如果現在請求的是 /index.php,根據配置文件,nginx 知道這個不是靜態文件,需要去找 PHP 解析器來處理,那麼他會把這個請求簡單處理後交給 PHP 解析器。Nginx 會傳哪些數據給 PHP 解析器呢?url、查詢字符串、POST 數據、HTTP header 等等,CGI 就是規定要傳哪些數據、以什麼樣的格式傳遞給後方處理這個請求的協議。
當 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 是什麼

PHP-FPM 是一個實現了 FastCgi 的程序,被 PHP 官方收錄。

PHP 的解釋器是 php-cgi,它只是個 CGI 程序,只能解析請求,返回結果,不會進程管理。所以就出現了一些能夠調度 php-cgi 進程的程序,比如說由 lighthttpd 分離出來的 spawn-fcgi。PHP-FPM 也是這麼個東西,在長時間的發展後,逐漸得到了大家的認可,也越來越流行。


# ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

fastcgi 是 app server 和web server 之間的通信協議。 

正常架構 app server 是master,web server是clientphp-fpm 帶兩個功能:
1.實現了一個支持fastcgi協議的server程序 
2. 進程管理器有了php-fpm,就可以把php腳本變成 多進程模式,採用fastcgi協議的app server,和web server進行通信你可以參考 python web 程序的9種部署方式 這篇文字。


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

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