CGI
CGI(Common Gateway Interface根穷,通用網(wǎng)關接口 ),描述了服務器和客戶端請求處理程序(通常就是瀏覽器)之間傳輸數(shù)據(jù)的一種標準溶浴。
它最初是在1993年由NCSA(美國國家超級電腦應用中心)為NCSA HTTPd Web服務器開發(fā)的管引。
CGI的第一個實現(xiàn)是采用Perl編寫的。Perl被廣泛用于編寫CGI程序褥伴,但CGI本身是獨立于任何語言的重慢。事實上饥臂,CGI程序可以使用任何腳本語言甚至是編譯型語言分別獨立實現(xiàn)隅熙,比如Unix Shell核芽、Python、Ruby轧简、PHP、C/C++等拳芙。
CGI的工作方式大致可以描述為:
- Step0 普通用戶通過瀏覽器(或者是表單提交、或者是直接訪問URL)發(fā)送請求給Web服務器
- Step1 Web服務器接收到請求后分飞,啟動CGI程序浆竭,通過環(huán)境變量惨寿、標準輸入等傳遞數(shù)據(jù),將請求轉交給對應的CGI進程
- Step2 CGI進程啟動解析器裂垦,或者訪問數(shù)據(jù)庫蕉拢、或者完成相關計算、或者與其它第三方進行交互
- Step3 在CGI程序處理完成后晕换,通過標準輸出將處理結果返回給Web服務器
- Step4 Web服務器收到結果后,構建Response返回給客戶端益愈,并殺死CGI進程
總結來說夷家,CGI采用的是“fork-and-execute”的工作模式,其缺點在于:效率低下摸袁,每個請求都需要fork一個新的CGI進程去處理义屏。當請求量增大時服務器很快將被壓垮。
為了提升CGI工作性能闽铐,有一種辦法是,將腳本解釋器直接作為模塊集成在Web服務器中添谊,例如:Apache的mod_perl模塊察迟,這樣就能夠避免重復載入和初始化解釋器耳高。不過這只是針對那些解釋型語言而言的所踊,使用諸如C一類的編譯型語言則可以避免這種額外負荷。由于C及其他編譯語言的程序與解釋語言程序相比碌燕,前者的運行速度更快继薛、對操作系統(tǒng)的負荷更小,使用編譯語言程序是可能達到更高執(zhí)行效率的遏考。然而因為開發(fā)效率等因素,在目前解釋型語言還是最合適的青团。
另一個辦法就是FastCGI技術咖楣。
FastCGI
FastCGI(快速通用網(wǎng)關接口),是CGI的增強版本娃肿。其目的在于瘪松,減少Web服務器與CGI程序之間交互的開銷,使得服務器可以同時處理更多的請求宵睦。
與CGI“fork-and-execute”的工作模式不同,F(xiàn)astCGI像是一個常駐型的CGI桐智,它使用持續(xù)的進程來處理一連串的請求烟馅。這些進程由FastCGI進程管理器管理,而不是Web服務器刊驴。當進來一個請求時,Web服務器把環(huán)境變量和這個頁面請求通過一個unix domain socket(比如FastCGI進程與Web服務器都位于本地)或者一個TCP連接(FastCGI進程部署在遠端)傳遞給FastCGI進程舅柜。
- Step1 Web服務器啟動時躲惰,初始化FastCGI執(zhí)行環(huán)境,例如apache mod_fastcgi础拨、nginx ngx_http_fastcgi_module、lighttpd mod_fastcgi
- Step2 FastCGI進程管理器自身初始化滔蝉,啟動多個CGI解釋器進程并等待來自Web服務器的連接
- Step3 當客戶端請求到達Web服務器時僚焦,Web服務器將請求通過socket方式轉發(fā)到FastCGI主進程曙痘,主進程選擇并連接到一個CGI解釋器。Web服務器將CGI環(huán)境變量和標準輸入發(fā)送到FastCGI子進程
- Step4 FastCGI子進程完成處理后名扛,將標準輸出和錯誤信息通過同一socket返回給Web服務器茧痒,并關閉連接
- Step5 FastCGI子進程接著等待下一個新的連接
不足之處:
PHP-CGI
PHP-CGI是PHP自帶的FastCGI管理器。
不足之處:
- 變更php.ini配置后弄企,需重啟PHP-CGI才能生效区拳,不能平滑重啟
- 直接殺死PHP-CGI進程,PHP就不能運行了(PHP-FPM和Spawn-FCGI就沒有這個問題了樱调,守護進程會平滑地重新生成新的子進程)
PHP-FPM
PHP-FPM是一個PHP FastCGI管理器笆凌,最初它只是PHP源碼的一個補丁,而從PHP 5.3.3開始乞而,已經(jīng)被集成到了PHP源碼中。與原生的PHP-CGI相比欠啤,它提供了更加友好的管理方式,可以有效控制內存和進程跪妥、可以平滑重載PHP配置眉撵。
Spawn-FCGI
Spawn-FCGI是一個通用的FastCGI管理器,起初它是lighttpd的一部分纽疟。目前,Spawn-FCGI已經(jīng)獨立成為一個項目散吵,性能較以往更加穩(wěn)定蟆肆。
WSGI
But,事情總是還有改進的余地的枚冗,F(xiàn)astCGI這套工作模式實際上沒有什么太大缺陷蛇损,但是有些不安分的Python程序猿覺得,F(xiàn)astCGI標準下寫異步的Web服務還是不太方便淤齐,如果能夠收到請求后CGI端去處理,處理完畢后通過Callback回調來返回結果稚疹,那樣豈不是很Coooool锈死?!所以WSGI就被創(chuàng)造出來了:
以上引文很好地說明了WSGI的來歷其屏。WSGI(Web Server Gateway Interface)是專門為Python定義的Web服務器和Web應用程序或框架之間的一種簡單而通用的接口缨该。
其工作方式大致是:當Web服務器接收到一個請求后,可以通過Socket把環(huán)境變量和一個callback回調函數(shù)傳遞給后端Web應用程序蛤袒,Web應用程序處理完成后,調用callback函數(shù)妙真,把結果返回給WebServer。
這種方式的優(yōu)點有:
- 異步化练般,通過callback將Web請求的工作拆解開锈候,可以很方便地在一個線程空間里同時處理多個Web請求
- 方便進行各種負載均衡和請求轉發(fā),不會造成后端Web應用阻塞
參考資料: