Fast CGI 工作原理


CGI的歷史

    早期的webserver只處理html等靜態文件,但是隨着技術的發展,出現了像php等動態語言。 

    webserver處理不了了,怎么辦呢?那就交給php解釋器來處理吧! 

    交給php解釋器處理很好,但是,php解釋器如何與webserver進行通信呢?

    為了解決不同的語言解釋器(如php、python解釋器)與webserver的通信,於是出現了cgi協議。只要你按照cgi協議去編寫程序,就能實現語言解釋器與webwerver的通信。如php-cgi程序。

FastCGI的改進

    有了cgi協議,解決了php解釋器與webserver通信的問題,webserver終於可以處理動態語言了。但是,webserver每收到一個請求,都會去fork一個cgi進程,請求結束再kill掉這個進程。這樣有10000個請求,就需要fork、kill php-cgi進程10000次。

    有沒有發現很浪費資源?

    於是,出現了cgi的改良版本,fast-cgi。fast-cgi每次處理完請求后,不會kill掉這個進程,而是保留這個進程,使這個進程可以一次處理多個請求。這樣每次就不用重新fork一個進程了,大大提高了效率。

PHP-FPM是什么

        php-fpm即php-Fastcgi Process Manager. 

        php-fpm是 FastCGI 的實現,並提供了進程管理的功能。 

        進程包含 master 進程和 worker 進程兩種進程。 

        master 進程只有一個,負責監聽端口,接收來自 Web Server 的請求,而 worker 進程則一般有多個(具體數量根據實際需要配置),每個進程內部都嵌入了一個 PHP 解釋器,是 PHP 代碼真正執行的地方。

FastCGI是什么?

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

        FastCGI的官方站點在http://www.fastcgi.com

FastCGI的工作原理是

        1、Web Server 啟動時載入FastCGI進程管理器(IIS ISAPI或Apache Module,nginx 下 fastcgi 與服務器是分離的,fastcgi 可有 lighttpd 下的spawan-cgi或者 php-fpm 來管理));

        2、FastCGI進程管理器自身初始化,啟動多個CGI解釋器進程 (在任務管理器中可見多個php-cgi.exe)並等待來自Web Server的連接。

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

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

        在上述情況中,你可以想象CGI通常有多慢。每一個Web請求PHP都必須重新解析php.ini、重新載入全部dll擴展並重初始化全部數據結構。使用FastCGI,所有這些都只在進程啟動時發生一次。一個額外的好處是,持續數據庫連接(Persistent database connection)可以工作。

總結

        nginx與php-fpm的結合,完整的流程是這樣的:

 
 

為什么要使用FastCGI,而不是多線程CGI解釋器?

        這可能出於多方面的考慮,例如:

        1、你無論如何也不能在windows平台上穩定的使用多線程CGI解釋器,無論是IIS ISAPI方式還是APACHE Module方式,它們總是運行一段時間就崩潰了。奇怪么?但是確實存在這樣的情況!當然,也有很多時候你能夠穩定的使用多線程CGI解釋器,但是,你有可能發現網頁有時候會出現錯誤,無論如何也找不到原因,而換用FastCGI方式時這種錯誤的概率會大大的降低。我也不清楚這是為什么,我想獨立地址空間的CGI解釋器可能終究比共享地址空間的形式來得穩定一點點。

        2、性能!性能?可能么,難道FastCGI比多線程CGI解釋器更快?但有時候確實是這樣,只有測試一下你的網站,才能最后下結論。原因嘛,我覺得很難講,但有資料說在Zend WinEnabler的時代,Zend原來也是建議在Windows平台下使用FastCGI而不是IIS ISAPI或Apache Module,不過現在Zend已經不做這個產品了。

FastCGI的技術原理

        如果想了解FastCGI的技術原理就要了解何為”短生存期應用程序”,何為”長生存期應用程序”。

        先從CGI技術開刀,以下是CGI技術的理論:每次當客戶請求一個CGI的時候,Web服務器就請求操作系統生成一個新的CGI進程。當CGI滿足要求后,服務器就殺死這個進程。服務器對客戶端的每個請求都要重復這樣的過程。

        而FastCGI技術的理論為:FastCGI程序一旦產生后,他可以持續工作,足夠滿足客戶的請求直到被明確的終止。如果你希望通過協同處理來提高程序的性能,你可以請求Web服務器運行多個FastCGI 應用程序的副本。

        CGI就是所謂的短生存期應用程序,FastCGI就是所謂的長生存期應用程序。

        由於FastCGI程序並不需要不斷的產生新進程,可以大大降低服務器的壓力。並且產生較高的應用效率。

        自今,較為流行的Java語言Servlet技術在設計上是以參考FastCGI的技術運行所設計。

FastCGI的特點

        1. 打破傳統頁面處理技術

                傳統的頁面處理技術,程序必須與Web服務器或Application服務器處於同一台服務器中。這種歷史已經早N年被FastCGI技術所打破, FastCGI技術的應用程序可以被安裝在服務器群中的任何一台服務器,而通過TCP/IP協議與Web服務器通訊,這樣做既適合開發大型分布式Web 群,也適合高效數據庫控制。

        2. 明確的請求模式

                CGI技術沒有一個明確的角色,在FastCGI程序中,程序被賦予明確的角色(響應器角色、認證器角色、過濾器角色)。

        3. 合理的程序結構

                起初,真的很討厭FastCGI應用程序的結構要求。沒關系,您經過一段時間編寫后就會喜歡這種結構,只有這種完全規范的結構才能讓您的程序更有效率。

Fastcgi到底是什么樣的技術

        注:本人對LAMP,python了解不是很多,此文是我的個人理解,如果有誤忘告知

        自從接觸rubyonrails以來,fastcgi這個技術標准就進入了我的視線,從技術角度看,fastcgi的優點還是很多的,作為一種替代cgi的技術標准, fastcgi有如下優點(穩定,安全,高性能,方便擴展)

        從穩定性上看, fastcgi是以獨立的進程池運行來cgi,單獨一個進程死掉,系統可以很輕易的丟棄,然后重新分配新的進程來運行邏輯.

        從安全性上看, fastcgi和宿主的server完全獨立, fastcgi怎么down也不會把server搞垮,        

        從性能上看, fastcgi把動態邏輯的處理從server中分離出來, 大負荷的IO處理還是留給宿主server, 這樣宿主server可以一心一意作IO,對於一個普通的動態網頁來說, 邏輯處理可能只有一小部分, 大量的圖片等靜態IO處理完全不需要邏輯程序的參與(注1)

        從擴展性上講, fastcgi是一個中立的技術標准, 完全可以支持任何語言寫的處理程序(php,java,python…)

        但是讓我感到迷惑不解的是,apache對fastcgi的支持mod_fastcgi簡直就是一塌糊塗, 最新的穩定版本居然還是2003年的,snap也只到2004年, 在1.3下面還勉強可以用, 在apache2.0上更是被報告無法穩定運行.fastcgi在[lighttpd][]上表現還算不錯, 但是lighttpd在用戶群,兼容性上還不夠主流(也就在linux上面表現不錯, 沒有正式的windows版本, solaris下面也有bug). 另外fastcgi也缺乏發展,讓人有被廢棄掉了的感覺.(ruby的dbi也是這個狀況). 和其他日新月異的技術標准比, fastcgi地位尷尬

        直到我看到這篇文章才明白,fastcgi真是的命苦.(呵呵,以下的內容取自該文章)

        從名字上看fastcgi是fast的cgi的,屬於改良派.從理論上,他可以很多程序語言接口來開發動態web,但是這些程序語言每一個都是走完全革命的道路. java陣營就自己搞了一套j2ee server標准,要協作也直接找apache或者IIS談,瞧不上fastcgi. aspx直接和IIS是親兄弟,沒有fastcgi的份. 剩下的php因為太流行(LAMP),和apache是鐵哥們,一個mod_php就解決了,簡單方便, python社區的牛人太多,精力旺盛,人家搞了個SCGI玩,和fastcgi比是有過之而無不及. 等到rails出山的時候, fastcgi真的算是老態龍鍾了.

        rails的出現使得fastcgi重新煥發了青春, apache也開始重新構建新的mod_proxy_fcgi,但是它的前途還不能說是一片光明, 我覺得至少有以下幾個問題

        目前的fastcgi和server溝通還不夠智能,一個fastcgi進程如果執行時間過長會被當成是死進程殺掉重起,這樣在處理長時間任務的時候很麻煩.這樣做也使得fastcgi無法允許聯機調試.

        SCGI等類似技術的都可以替換fastcgi, SCGI在python中很成功,功能完備,目前SCGI也開始支持rails了

        隨着rails的流行,一個獨立的mod_rails是可能出現的,而且ruby自身的webserver也開始涌現,以后極有可能自己搞一套東西連接主流的webserver.fastcgi設計的時候是想作common gateway interface(cgi)的,但是這個目標的現在看來已經不適合了

        總結: 我覺得fastcgi的前途不明朗, 但是目前來說,他也是rails唯一可以進入生產環境的工具,只用搞懂怎么配就可以了,沒有必要深入研究.

        注1: 有時候邏輯也會參與圖片的生成,這時候圖片的IO處理就需要動態程序介入了,此時fastcgi技術上的優勢雖然體現不出來,但是也不會比其他技術標准差.

 

cgi、fast-cgi協議

cgi的歷史

早期的webserver只處理html等靜態文件,但是隨着技術的發展,出現了像php等動態語言。 

webserver處理不了了,怎么辦呢?那就交給php解釋器來處理吧! 

交給php解釋器處理很好,但是,php解釋器如何與webserver進行通信呢?

為了解決不同的語言解釋器(如php、python解釋器)與webserver的通信,於是出現了cgi協議。只要你按照cgi協議去編寫程序,就能實現語言解釋器與webwerver的通信。如php-cgi程序。

 
 

鏈接:https://www.jianshu.com/p/415b83972795


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM