1. 程式人生 > >WSGI——python web 服務器網關接口

WSGI——python web 服務器網關接口

瓶頸 數據交互 結果 ash orm 占用 預處理 描述 接口規範

轉載請註明原文地址:https://www.cnblogs.com/ygj0930/p/10826084.html

一:服務器、服務器軟件、應用程序(後臺)

我們常說“服務器”,實際上服務器是一個很寬泛的概念。

服務器包括服務器硬件、服務器程序、以及部署在服務器上的應用程序。

服務器硬件:也稱伺服器,是提供計算服務的硬件設備,包括處理器、硬盤、內存、系統總線等。

服務器軟件:光有服務器硬件是無法提供服務的,至少需要有運行於服務器之上的操作系統、數據庫軟件、以及提供部署功能的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 服務器網關接口。

二:WSGI簡介

PythonWeb服務器網關接口(Python Web Server Gateway Interface,縮寫為WSGI)是一個協議,是 Python應用程序或框架 與 Web容器

之間的一種接口規範。

只要雙方都按照這個規範,分別去實現自己需要做的事,那麽二者就可以順利地進行通信。

WSGI協議主要包括serverapplication兩部分。

三:WSGI server接口

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接口

WSGI application接口 接收由server轉發過來的request,處理請求,並將處理結果返回給server

接口的實現方式:

  1. 應用程序必須是一個可調用的對象
    可調用的對象有三種:
    1. 一個函數
    2. 一個類,必須實現__call__()方法
    3. 一個類的實例
  2. 這個對象接收兩個參數
    從源碼中,我們可以看到,這兩個參數是environ, start_response. 以可調用對象為一個類為例:

    class application:
        def __call__(self, environ, start_response):
            pass
  3. 可調用對象需要返回一個可叠代的值。以可調用對象為一個類為例:

    class application:
        def __call__(self, environ, start_response):
            return [xxx]

五:Middleware 中間件

middleware是介於服務器程序和應用程序中間的部分,middleware對於服務器程序(web容器)和應用程序來說都是透明的:對服務器程序來說,中間件扮演應用程序,對應用程序來說,中間件扮演服務器程序。

因此,中間件程序需要同時實現wsgi server與wsgi application接口,可以在WSGI服務器與WSGI應用之間起調節作用。
中間件是一個很強大的領域,相信很多同學都聽說或正在擔任中間件的開發工作。

我們知道,應用程序主要是做業務邏輯實現的,那麽,在請求到達應用程序之前,我們可以用來做些什麽呢?一個很簡單的場景,就是做請求的預處理或者基本信息提取。

上面提到,WSGI Server調用WSGI Application時,需要兩個參數:environstart_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協議其實是定義了一種serverapplication解耦的規範,即可以有多個實現WSGI server的服務器,也可以有多個實現WSGI application的框架,那麽就可以選擇任意的serverapplication組合實現自己的web應用。例如uWSGIGunicorn都是實現了WSGI server協議的服務器,DjangoFlask是實現了WSGI application協議的web框架,可以根據項目實際情況搭配使用。

七:擴展:uwsgi

uwsgi:與WSGI一樣是一種通信協議,是uWSGI服務器的獨占協議,用於定義傳輸信息的類型(type of information),每一個uwsgi packet4byte為傳輸信息類型的描述,與WSGI協議是兩種東西,據說該協議是fcgi協議的10倍快。

八:擴展:uWSGI

uWSGI旨在為部署分布式集群的網絡應用開發一套完整的解決方案。主要面向web及其標準服務。由於其可擴展性,能夠被無限制的擴展用來支持更多平臺和語言。uWSGI是一個web服務器,實現了WSGI協議,uwsgi協議,http協議等。
uWSGI的主要特點是:

  • 超快的性能
  • 低內存占用
  • app管理
  • 詳盡的日誌功能(可以用來分析app的性能和瓶頸)
  • 高度可定制(內存大小限制,服務一定次數後重啟等)

uWSGI服務器自己實現了基於uwsgi協議的server部分,我們只需要在uwsgi的配置文件中指定application的地址,uWSGI就能直接和應用框架中的WSGI application通信。

WSGI——python web 服務器網關接口