咱們常說「服務器」,實際上服務器是一個很寬泛的概念。html
服務器包括服務器硬件、服務器程序、以及部署在服務器上的應用程序。python
服務器硬件:也稱伺服器,是提供計算服務的硬件設備,包括處理器、硬盤、內存、系統總線等。web
服務器軟件:光有服務器硬件是沒法提供服務的,至少須要有運行於服務器之上的操做系統、數據庫軟件、以及提供部署功能的web容器等程序。這些軟件與服務器硬件一塊兒,共同組成了咱們概念中的「服務器」。數據庫
應用程序(後臺程序):應用程序是運行在服務器上,處理請求並返回響應的程序,咱們平常所說的「web開發」、「後臺開發」作的就是web應用程序的開發工做。通常,web應用程序須要部署於web容器中,而且與數據庫產生數據交互。三者關係大概爲:web容器負責實現一些通訊協議,而且監聽服務器硬件的網關、端口,接收請求,並轉發給web應用程序;web應用程序接收請求,提取請求相關信息與參數,調用中間件或者自身實現的業務邏輯(此過程或許會與數據庫產生數據交互),並將處理結果以http響應的形式返回給web容器;web容器再將接收到的響應返回給瀏覽器進行顯示。瀏覽器
在上面的過程當中,說起到了 web容器 與 應用程序 之間的請求轉發和響應通訊,那麼問題來了:web容器 有 Apahce、Nginx、Gunicorn等多種選擇,而 應用程序 也可能選用Flask、Django等等各類框架進行開發,難道咱們須要針對不一樣的容器或開發框架,都本身去實現一遍它們的通訊邏輯嗎?固然不是。爲了創建起web容器與應用程序之間的通訊規範,因而有了咱們所說的——WSGI,Web Server Gateway Interface,Python Web 服務器網關接口。服務器
PythonWeb服務器網關接口(Python Web Server Gateway Interface,縮寫爲WSGI)是一個協議,是 Python應用程序或框架 與 Web容器 之間的一種接口規範。網絡
只要雙方都按照這個規範,分別去實現本身須要作的事,那麼兩者就能夠順利地進行通訊。app
WSGI
協議主要包括server
和application
兩部分。框架
WSGI server接口
負責從客戶端接收請求,將request
轉發給application
,並將application
返回的response
返回給客戶端。分佈式
咱們經常使用的web容器,如Apahce、Nginx、Gunicorn等都實現了這個接口。
接口實現方式:
def run(application): #服務器程序調用應用程序實例 environ = {} #設定參數 def start_response(xxx): #設定參數 pass result = application(environ, start_response) #調用應用程序實例的__call__函數 def write(data): pass def data in result: #迭代訪問 write(data)
服務器程序主要作了如下的事: 1. 設定應用程序所須要的參數 2. 調用應用程序 3. 迭代訪問應用程序的返回結果,並傳給客戶端
WSGI application接口
接收由server
轉發過來的request
,處理請求,並將處理結果返回給server
。
接口的實現方式:
這個對象接收兩個參數
從源碼中,咱們能夠看到,這兩個參數是environ, start_response. 以可調用對象爲一個類爲例:
class application: def __call__(self, environ, start_response): pass
可調用對象須要返回一個可迭代的值。以可調用對象爲一個類爲例:
class application: def __call__(self, environ, start_response): return [xxx]
middleware是介於服務器程序和應用程序中間的部分,middleware對於服務器程序(web容器)和應用程序來講都是透明的:對服務器程序來講,中間件扮演應用程序,對應用程序來講,中間件扮演服務器程序。
所以,中間件程序須要同時實現wsgi server與wsgi application接口,能夠在WSGI服務器與WSGI應用之間起調節做用。
中間件是一個很強大的領域,相信不少同窗都據說或正在擔任中間件的開發工做。
咱們知道,應用程序主要是作業務邏輯實現的,那麼,在請求到達應用程序以前,咱們能夠用來作些什麼呢?一個很簡單的場景,就是作請求的預處理或者基本信息提取。
上面提到,WSGI Server調用WSGI Application時,須要兩個參數:environ
和start_response,其中,
environ
是一個字典,它來自CGI,詳情請看文檔:The Common Gateway Interface Specification
文中「Environment variables」,列舉了environ字典中包含的信息,主要有:
AUTH_TYPE
CONTENT_LENGTH #HTTP請求中Content-Length的部分 CONTENT_TYPE #HTTP請求中Content-Tpye的部分 GATEWAY_INTERFACE PATH_INFO #URL路徑除了起始部分後的剩餘部分,用於找到相應的應用程序對象,若是請求的路徑就是根路徑,這個值爲空字符串 PATH_TRANSLATED QUERY_STRING #URL路徑中?後面的部分 REMOTE_ADDR REMOTE_HOST REMOTE_IDENT REMOTE_USER REQUEST_METHOD #HTTP 請求方法,例如 "GET", "POST" SCRIPT_NAME #URL路徑的起始部分對應的應用程序對象,若是應用程序對象對應服務器的根,那麼這個值能夠爲空字符串 SERVER_NAME SERVER_PORT SERVER_PROTOCOL #客戶端請求的協議(HTTP/1.1 HTTP/1.0) SERVER_SOFTWARE
以及客戶端發起HTTP時所攜帶過來的一些關於客戶端的信息:
HTTP_HOST = 客戶端host
HTTP_ACCEPT = 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' HTTP_ACCEPT_ENCODING = 'gzip,deflate,sdch' HTTP_ACCEPT_LANGUAGE = 'en-US,en;q=0.8,zh;q=0.6,zh-CN;q=0.4,zh-TW;q=0.2' HTTP_CONNECTION = 'keep-alive' HTTP_USER_AGENT = 客戶端代理信息(瀏覽器、內核版本等)
WSGI
協議實際上是定義了一種
server
與
application
解耦的規範,便可以有多個實現
WSGI server
的服務器,也能夠有多個實現
WSGI application
的框架,那麼就能夠選擇任意的
server
和
application
組合實現本身的
web
應用。例如
uWSGI
和
Gunicorn
都是實現了
WSGI server
協議的服務器,
Django
,
Flask
是實現了
WSGI application
協議的
web
框架,能夠根據項目實際狀況搭配使用。
WSGI
同樣是一種通訊協議,是
uWSGI
服務器的獨佔協議,用於定義傳輸信息的類型(
type of information
),每個
uwsgi packet
前
4byte
爲傳輸信息類型的描述,與WSGI協議是兩種東西,聽說該協議是
fcgi
協議的10倍快。
uWSGI
旨在爲部署分佈式集羣的網絡應用開發一套完整的解決方案。主要面向web
及其標準服務。因爲其可擴展性,可以被無限制的擴展用來支持更多平臺和語言。uWSGI
是一個web
服務器,實現了WSGI
協議,uwsgi
協議,http
協議等。uWSGI
的主要特色是:
app
管理app
的性能和瓶頸)uWSGI
服務器本身實現了基於uwsgi
協議的server
部分,咱們只須要在uwsgi
的配置文件中指定application
的地址,uWSGI
就能直接和應用框架中的WSGI application
通訊。