一直對這四者的概念和區別很模糊,如今就特地梳理一下它們的關係與區別。php
CGIpython
CGI即通用網關接口(Common Gateway Interface),是外部應用程序(CGI程序)與Web服務器之間的接口標準,是在CGI程序和Web服務器之間傳遞信息的規程。CGI規範容許 Web服務器執行外部程序,並將它們的輸出發送給Web瀏覽器,CGI將Web的一組簡單的靜態超媒體文檔變成一個完整的新的交互式媒體。通俗的講CGI 就像是一座橋,把網頁和WEB服務器中的執行程序鏈接起來,它把HTML接收的指令傳遞給服務器的執行程序,再把服務器執行程序的結果返還給HTML頁。 CGI 的跨平臺性能極佳,幾乎能夠在任何操做系統上實現。nginx
CGI方式在遇到鏈接請求(用戶請求)先要建立cgi的子進程,激活一個CGI進程,而後處理請求,處理完後結束這個子進程。這就是fork- and-execute模式。因此用cgi方式的服務器有多少鏈接請求就會有多少cgi子進程,子進程反覆加載是cgi性能低下的主要緣由。當用戶請求數 量很是多時,會大量擠佔系統的資源如內存,CPU時間等,形成效能低下。git
CGI腳本工做流程:github
FastCGIweb
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 程序能夠在網站服務器之外的主機上執行而且接受來自其它網站服務器來的請求。apache
FastCGI是語言無關的、可伸縮架構的CGI開放擴展,其主要行爲是將CGI解釋器進程保持在內存中並所以得到較高的性能。衆所周知,CGI解 釋器的反覆加載是CGI性能低下的主要緣由,若是CGI解釋器保持在內存中並接受FastCGI進程管理器調度,則能夠提供良好的性能、伸縮性、 Fail-Over特性等等。FastCGI接口方式採用C/S結構,能夠將HTTP服務器和腳本解析服務器分開,同時在腳本解析服務器上啓動一個或者多 個腳本解析守護進程。當HTTP服務器每次遇到動態程序時,能夠將其直接交付給FastCGI進程來執行,而後將獲得的結果返回給瀏覽器。這種方式可讓 HTTP服務器專注地處理靜態請求或者將動態腳本服務器的結果返回給客戶端,這在很大程度上提升了整個應用系統的性能。編程
FastCGI的工做流程:windows
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的不足:
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代碼分析以下:
很顯然,Spawn-FCGI也是 pre-fork 模型,只是用了上古C語言編寫,充滿了N多 unix下暗黑編程技巧。
Spawn-FCGI功能很單一:
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 的大部分附加功能,對於高負載網站是很是有用的。它的功能包括:
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服務器的角度來講,中間件扮演應用程序,而從應用程序的 角度來講,中間件扮演服務器。「中間件」組件能夠執行如下功能:
之前,如何選擇合適的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 Server/gateway
wsgi server能夠理解爲一個符合wsgi規範的web server,接收request請求,封裝一系列環境變量,按照wsgi規範調用註冊的wsgi app,最後將response返回給客戶端。文字很難解釋清楚wsgi server究竟是什麼東西,以及作些什麼事情,最直觀的方式仍是看wsgi server的實現代碼。以python自帶的wsgiref爲例,wsgiref是按照wsgi規範實現的一個簡單wsgi server。它的代碼也不復雜。
二、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。這麼空講感受很虛,對着下面這個簡單的例子看就明白不少了。
三、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倍那麼快。
另外一篇文章用類比的方法幫助理解:http://sunxiunan.com/?p=1778
總結
從CGI、FastCGI、WSGI、uWSGI,它們的主要功能就是CGI的做用—HTTP服務器與你的或其它機器上的程序進行「交談」的一種工具,其程序須運行在網絡服務器上,是從遠到近逐步完善的過程。CGI是基礎,fastCGI解決了其性能低下、佔用系統和內存高的缺點。WSGI相比較於fastCGI,解決了Web應用框架的選擇將限制可用的Web服務器的選擇這一問題,只要遵守WSGI協議,WSGI應用(Application)均可以在任何服務器(Server)上運行。基於Python的Web項目部署時用wsgi和fastcgi很麻煩,因此像php-cgi同樣監聽同一端口,進行統一管理和負載平衡的uWSG便應運而生,它相較於fastCGI和WSGI的性能要高,佔用的內存要少不少。