1. 程式人生 > >Nginx、WSGI、 uWSGI、 uwsgi的區別

Nginx、WSGI、 uWSGI、 uwsgi的區別

當我們部署完一個應用程式,瀏覽網頁時具體的過程是怎樣的呢?首先我們得有一個 Web 伺服器來處理 HTTP 協議的內容,Web 伺服器獲得客戶端的請求,交給應用程式,應用程式處理完,返回給 Web 伺服器,這時 Web 伺服器再返回給客戶端。Web 伺服器與應用程式之間顯然要進行互動,這時就出現了很多 Web 伺服器與應用程式之間互動的規範,最早出現的是 CGI,後來又出現了改進 CGI 效能的FasgCGI,Java 專用的 Servlet 規範,Python 專用的 WSGI 規範等等。有了統一標準,程式的可移植性就大大提高了。這裡我們只介紹 WSGI。

WSGI 全稱是 Web Server Gateway Interface,也就是 Web 伺服器閘道器介面,它是 Python 語言定義出來的 Web 伺服器和 Web 應用程式之間的簡單而通用的介面,基於現存的 CGI 標準設計,後來在很多其他語言中也出現了類似的介面。 總的來說,WSGI 可以分為伺服器和應用程式兩個部分,實際上可以將 WSGI 理解為伺服器與應用程式之間的一座橋,橋的一邊是伺服器,另一邊是應用程式。

按照 web 元件分類,WSGI 內部可以分為三類,web 應用程式,web 伺服器,web 中介軟體。應用程式端的部分通過Python 語言的各種 Web 框架實現,比如 Flask,Django這些,有了框架,開發者就不需要處理 WSGI,框架會幫忙解決這些,開發者只需處理 HTTP 請求和響應,web 伺服器的部分就要複雜一點,可以通過 uWSGI 實現,也可以用最常見的 Web 伺服器,比如 Apache、Nginx,但這些 Web 伺服器沒有內建 WSGI 的實現,是通過擴充套件完成的。如 Apache,通過擴充套件模組 mod_wsgi 來支援WSGI,Nginx可以通過代理的方式,將請求封裝好,交給應用伺服器,比如 uWSGI。uWSGI 可以完成 WSGI 的服務端,程序管理以及對應用的呼叫。WSGI 中介軟體的部分可以這樣理解:我們把 WSGI 看做橋,這個橋有兩個橋墩,一個是應用程式端,另一個是伺服器端,那麼橋面就是 WSGI 中介軟體,中介軟體同時具備伺服器、應用程式端兩個角色,當然也需要同時遵守 WSGI 伺服器和 WSGI 應用程式兩邊的限制和需要。更詳細的內容可以看

PEP-333 中介軟體的描述

Flask 依賴的 Werkzeug 就是一個 WSGI 工具包,官方文件的定義是 Werkzeug 是為 Python 設計的 HTTP和 WSGI 實用程式庫。我們需要注意的是,Flask 自帶的 Werkzeug 是用來開發的,並不能用於生產環境,Flask 是 Web 框架,而 Werkzeug 不是 Web框架,不是 Web 伺服器,它只是一個 WSGI 工具包,它在 Flask 的作用是作為 Web 框架的底層庫,它方便了我們的開發。

我們將 uwsgi 和 uWSGI 放在一起講解。uWSGI 是一個 Web 伺服器程式,WSGI,上面已經談到,是一種協議,uwsgi 也是一種協議,uWSGI 實現了 uwsgi、WSGI、http 等協議。 uwsgi 的介紹可以看

這裡,uwsgi 是 uWSGI 使用的一個自有的協議,它用4個位元組來定義傳輸資料型別描述。儘管都是協議,uwsgi 和 WSGI 並沒有聯絡,我們需要區分這兩個詞。

Nginx

Nginx 是高效的 Web 伺服器和反向代理伺服器,可以用作負載均衡(當有 n 個使用者訪問伺服器時,可以實現分流,分擔伺服器的壓力),與 Apache 相比,Nginx 支援高併發,可以支援百萬級的 TCP 連線,十萬級別的併發連線,部署簡單,記憶體消耗少,成本低,但 Nginx 的模組沒有 Apache 豐富。Nginx 支援 uWSGI 的 uwsgi 協議,因此我們可以將 Nginx 與 uWSGI 結合起來,Nginx 通過 uwsgi_pass 將動態內容交給 uWSGI 處理。

uWSGI 和 Nginx 的關係

從上面的講解中,我們知道,uWSGI 可以起到 Web 伺服器的作用,那麼為什麼有了 uWSGI 還需要 Nginx 呢?

最普遍的說法是 Nginx 對於處理靜態檔案更有優勢,效能更好。其實如果是小網站,沒有靜態檔案需要處理,只用 uWSGI 也是可以的,但加上 Nginx 這一層,優勢可以很具體:

  1. 對於運維來說比較方便,如果伺服器被某個 IP 攻擊,在 Nginx 配置檔案黑名單中新增這個 IP 即可,如果只用 uWSGI,那麼就需要在程式碼中修改了。另一方面,Nginx 是身經百戰的 Web 伺服器了,在表現上 uWSGI 顯得更專業,比如說 uWSGI 在早期版本里是不支援 https 的,可以說 Nginx 更安全。
  2. Nginx 的特點是能夠做負載均衡和 HTTP 快取,如果不止一臺伺服器,Nginx 基本就是必選項了,通過 Nginx,將資源可以分配給不同的伺服器節點,只有一臺伺服器,也能很好地提高效能,因為 Nginx 可以通過 headers 的Expires or E-Tag,gzip 壓縮等方式很好地處理靜態資源,畢竟是 C 語言寫的,呼叫的是 native 的函式,針對 I/O做了優化,對於動態資源來說,Nginx 還可以實現快取的功能,配合 CDN 優化(這是 uWSGI 做不到的)。Nginx 支援epoll/kqueue 等高效網路庫,能夠很好地處理高併發短連線請求,效能比 uWSGI 不知道高到哪裡去了。
  3. 如果伺服器主機上運行了PHP,Python 等語言寫的多個應用,都需要監聽80埠,這時候 Nginx 就是必選項了。因為我們需要一個轉發的服務。
WSGI:全稱是Web Server Gateway Interface,WSGI不是伺服器,python模組,框架,API或者任何軟體,只是一種規範,描述web server如何與web application通訊的規範。要實現WSGI協議,必須同時實現web server和web application,當前執行在WSGI協議之上的web框架有Bottle, Flask, Django。
uwsgi:與WSGI一樣是一種通訊協議,是uWSGI伺服器的獨佔協議,用於定義傳輸資訊的型別(type of information)
uWSGI:是一個web伺服器,實現了WSGI協議、uwsgi協議、http協議等。
WSGI協議主要包括server和application兩部分:
WSGI server負責從客戶端接收請求,將request轉發給application,將application返回的response返回給客戶端;
WSGI application接收由server轉發的request,處理請求,並將處理結果返回給server。application中可以包括多個棧式的中介軟體(middlewares),這些中介軟體需要同時實現server與application,因此可以在WSGI伺服器與WSGI應用之間起調節作用:對伺服器來說,中介軟體扮演應用程式,對應用程式來說,中介軟體扮演伺服器。
WSGI協議其實是定義了一種server與application解耦的規範,即可以有多個實現WSGI server的伺服器,也可以有多個實現WSGI application的框架,那麼就可以選擇任意的server和application組合實現自己的web應用。例如uWSGI和Gunicorn都是實現了WSGI server協議的伺服器,Django,Flask是實現了WSGI application協議的web框架,可以根據專案實際情況搭配使用。

 

 

Nginx+uWSGI+應用程式的架構

image