CGI
CGI(Common Gateway Interface,通用網(wǎng)關(guān)接口 ),描述了服務(wù)器和客戶端請求處理程序(通常就是瀏覽器)之間傳輸數(shù)據(jù)的一種標準。
它最初是在1993年由NCSA(美國國家超級電腦應(yīng)用中心)為NCSA HTTPd Web服務(wù)器開發(fā)的。
CGI的第一個實現(xiàn)是采用Perl編寫的。Perl被廣泛用于編寫CGI程序,但CGI本身是獨立于任何語言的。事實上,CGI程序可以使用任何腳本語言甚至是編譯型語言分別獨立實現(xiàn),比如Unix Shell、Python、Ruby、PHP、C/C++等。

CGI的工作方式大致可以描述為:
- Step0 普通用戶通過瀏覽器(或者是表單提交、或者是直接訪問URL)發(fā)送請求給Web服務(wù)器
- Step1 Web服務(wù)器接收到請求后,啟動CGI程序,通過環(huán)境變量、標準輸入等傳遞數(shù)據(jù),將請求轉(zhuǎn)交給對應(yīng)的CGI進程
- Step2 CGI進程啟動解析器,或者訪問數(shù)據(jù)庫、或者完成相關(guān)計算、或者與其它第三方進行交互
- Step3 在CGI程序處理完成后,通過標準輸出將處理結(jié)果返回給Web服務(wù)器
- Step4 Web服務(wù)器收到結(jié)果后,構(gòu)建Response返回給客戶端,并殺死CGI進程
總結(jié)來說,CGI采用的是“fork-and-execute”的工作模式,其缺點在于:效率低下,每個請求都需要fork一個新的CGI進程去處理。當請求量增大時服務(wù)器很快將被壓垮。
為了提升CGI工作性能,有一種辦法是,將腳本解釋器直接作為模塊集成在Web服務(wù)器中,例如:Apache的mod_perl模塊,這樣就能夠避免重復載入和初始化解釋器。不過這只是針對那些解釋型語言而言的,使用諸如C一類的編譯型語言則可以避免這種額外負荷。由于C及其他編譯語言的程序與解釋語言程序相比,前者的運行速度更快、對操作系統(tǒng)的負荷更小,使用編譯語言程序是可能達到更高執(zhí)行效率的。然而因為開發(fā)效率等因素,在目前解釋型語言還是最合適的。
另一個辦法就是FastCGI技術(shù)。
FastCGI
FastCGI(快速通用網(wǎng)關(guān)接口),是CGI的增強版本。其目的在于,減少Web服務(wù)器與CGI程序之間交互的開銷,使得服務(wù)器可以同時處理更多的請求。
與CGI“fork-and-execute”的工作模式不同,F(xiàn)astCGI像是一個常駐型的CGI,它使用持續(xù)的進程來處理一連串的請求。這些進程由FastCGI進程管理器管理,而不是Web服務(wù)器。當進來一個請求時,Web服務(wù)器把環(huán)境變量和這個頁面請求通過一個unix domain socket(比如FastCGI進程與Web服務(wù)器都位于本地)或者一個TCP連接(FastCGI進程部署在遠端)傳遞給FastCGI進程。
- Step1 Web服務(wù)器啟動時,初始化FastCGI執(zhí)行環(huán)境,例如apache mod_fastcgi、nginx ngx_http_fastcgi_module、lighttpd mod_fastcgi
- Step2 FastCGI進程管理器自身初始化,啟動多個CGI解釋器進程并等待來自Web服務(wù)器的連接
- Step3 當客戶端請求到達Web服務(wù)器時,Web服務(wù)器將請求通過socket方式轉(zhuǎn)發(fā)到FastCGI主進程,主進程選擇并連接到一個CGI解釋器。Web服務(wù)器將CGI環(huán)境變量和標準輸入發(fā)送到FastCGI子進程
- Step4 FastCGI子進程完成處理后,將標準輸出和錯誤信息通過同一socket返回給Web服務(wù)器,并關(guān)閉連接
- 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相比,它提供了更加友好的管理方式,可以有效控制內(nèi)存和進程、可以平滑重載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服務(wù)還是不太方便,如果能夠收到請求后CGI端去處理,處理完畢后通過Callback回調(diào)來返回結(jié)果,那樣豈不是很Coooool?!所以WSGI就被創(chuàng)造出來了:
以上引文很好地說明了WSGI的來歷。WSGI(Web Server Gateway Interface)是專門為Python定義的Web服務(wù)器和Web應(yīng)用程序或框架之間的一種簡單而通用的接口。
其工作方式大致是:當Web服務(wù)器接收到一個請求后,可以通過Socket把環(huán)境變量和一個callback回調(diào)函數(shù)傳遞給后端Web應(yīng)用程序,Web應(yīng)用程序處理完成后,調(diào)用callback函數(shù),把結(jié)果返回給WebServer。
這種方式的優(yōu)點有:
- 異步化,通過callback將Web請求的工作拆解開,可以很方便地在一個線程空間里同時處理多個Web請求
- 方便進行各種負載均衡和請求轉(zhuǎn)發(fā),不會造成后端Web應(yīng)用阻塞
參考資料: