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

WSGI 全稱是 Web Server Gateway Interface,也就是 Web 服務器網關接口,它是 Python 語言定義出來的 Web 服務器和 Web 應用程序之間的簡單而通用的接口,基於現存的 CGI 標準設計,後來在不少其餘語言中也出現了相似的接口。 總的來講,WSGI 能夠分爲服務器和應用程序兩個部分,實際上能夠將 WSGI 理解爲服務器與應用程序之間的一座橋,橋的一邊是服務器,另外一邊是應用程序。python

按照 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 中間件的描述web

Flask 依賴的 Werkzeug 就是一個 WSGI 工具包,官方文檔的定義是 Werkzeug 是爲 Python 設計的 HTTP和 WSGI 實用程序庫。咱們須要注意的是,Flask 自帶的 Werkzeug 是用來開發的,並不能用於生產環境,Flask 是 Web 框架,而 Werkzeug 不是 Web框架,不是 Web 服務器,它只是一個 WSGI 工具包,它在 Flask 的做用是做爲 Web 框架的底層庫,它方便了咱們的開發。django

咱們將 uwsgi 和 uWSGI 放在一塊兒講解。uWSGI 是一個 Web 服務器程序,WSGI,上面已經談到,是一種協議,uwsgi 也是一種協議,uWSGI 實現了 uwsgi、WSGI、http 等協議。 uwsgi 的介紹能夠看這裏,uwsgi 是 uWSGI 使用的一個自有的協議,它用4個字節來定義傳輸數據類型描述。儘管都是協議,uwsgi 和 WSGI 並無聯繫,咱們須要區分這兩個詞。flask

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