nginx+flask02---概念

概念理解

wsgiref模塊是python提供的,用於測試和學習的簡單的WSGI服務器模塊。 
這個模塊監聽8000端口(監聽端口能夠改變),把Http請求,根據WSGI協議,轉換application函數中的environ參數,而後調用application函數。 
wsgiref會把application函數提供的響應頭設置轉換爲HTTP協議的響應頭,把application的返回(return)做爲響應體,根據HTTP協議,生成響應,返回給瀏覽器。php

 

- WSGI 
- uWSGI 
- uwsgi 
- Nginx 
html

瀏覽器發起請求,都是請求80端口python


WSGI 是一種協議,不是任何包不是任何服務器,就和 TCP 協議同樣。它定義了 Web 服務器和 Web 應用程序以前如何通訊的規範。 

至於爲何和 Python 扯在一塊兒?由於這個協議是由 Python 在 2003 年提出的。(參考:PEP-333 和 PEP-3333 ) 

> WSGI is the Web Server Gateway Interface. It is a specification that describes how a web server communicates with web applications, and how web applications can be chained together to process one request. 

uWSGI 是一個全功能的 HTTP 服務器,他要作的就是把 HTTP 協議轉化成語言支持的網絡協議。好比把 HTTP 協議轉化成 WSGI 協議,讓 Python 能夠直接使用。 

> The uWSGI project aims at developing a full stack for building hosting services. 

> Application servers (for various programming languages and protocols), proxies, process managers and monitors are all implemented using a common api and a common configuration style. 

uwsgi 是一種 uWSGI 的內部協議,使用二進制方式和其餘應用程序進行通訊。 

> The uwsgi (lowercase!) protocol is the native protocol used by the uWSGI server. 

> It is a binary protocol that can carry any type of data. The first 4 bytes of a uwsgi packet describe the type of the data contained by the packet. 

Nginx 是一個 Web 服務器其中的 HTTP 服務器功能和 uWSGI 功能很相似,可是 Nginx 還能夠用做更多用途,好比最經常使用的反向代理功能。 

因此用一張圖來描述一下這個過程: 
nginx

 

uWSGI配合Nginx反向代理

不少框架和應用服務器均可以對靜態文件的請求(如JavaScript、CSS、圖片等)返回來自應用的響應,不過更好的作法是用反向代理服務器(好比Nginx)來處理此類請求,減輕應用服務器的負載,得到更好的性能。web

隨着應用擴大,可能會須要分佈到不一樣的服務器(雲主機)上,此類需求在早期能夠用反向代理實現。apache

此外,Nginx的可擴展性(除了緩存以外,還有failover等其餘機制)對於一些比較複雜的Web應用也頗有幫助。django

一個簡單的服務器架構:編程

客戶端請求 ----> Nginx (反向代理) | /|\ | | `-> App. Server I. 127.0.0.1:8081 | `--> App. Server II. 127.0.0.1:8082 `----> App. Server III. 127.0.0.1:8083

注:只監聽127.0.0.1的應用只能從本地訪問,而若是設置成0.0.0.0就可以從外部訪問了。flask

 

 

flask,是一種python開發web的一種框架,相似的還有django,flask比較輕量,django適合大型項目。 flask框架寫的web,一般能夠直接運行起來就能夠訪問web了。可是這種方式只適合開發調試,前面已經提過。實際是它內部有一個web服務,叫wsgi。這個東西不是很全,只是做爲部分被提供在flask框架內。生產環境中,須要另外的web服務來掛起flak寫的網站。一般這個web服務就是uwsgi。稍後咱們會講到,怎麼去安裝配置uwsgi;api

而對於nginx,它扮演的是反向代理角色。在大型項目裏面經常扮演者反向代理和負載均衡的角色。  什麼意思呢,就是用戶發送的請求,所有經過這個nginx服務,nginx會去請求真正的內容服務器,也就是咱們部署好的,uwsgi服務。uwsgi服務將用戶須要的網頁和數據,送到nginx服務那,再由nginx推送給用戶。這個過程,對於用戶來講,只和uwsgi服務發生關係。真正的內容服務器是不可見的。 因此從安全的角度來講,這無疑更安全。 另一個緣由選擇nginx,是因爲nginx服務性能很穩定,高併發能力強。

 

 

uWSGI
咱們知道 Flask 中自帶了 web server,經過 Werkzeug,咱們能夠搭建 WSGI 服務,運行咱們的網站,但 Flask 是 Web 框架,並非 Web 服務器,儘管 Werkzeug 很強大,但只能用於開發,不能用於生產,對於 Web 服務器,咱們有更專業的選擇,那就是 uWSGI, uWSGI 是一個全站式的託管服務,它實現了應用服務器(支持多種編程語言)、代理、進程管理器、監視器。取名爲 uWSGI 是由於它最先實現的是 Python 語言的 WSGI。

uWSGI 包括四個部分:

uwsgi協議
web server 內置支持協議模塊
application 服務器協議支持模塊
進程控制程序
uWSGI 是 C 語言寫的,性能比較高。

 

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 處理。

官方文檔在這

最好的 Nginx 教程在這

uWSGI 和 Nginx 的關係
從上面的講解中,咱們知道,uWSGI 能夠起到 Web 服務器的做用,那麼爲何有了 uWSGI 還須要 Nginx 呢?

最廣泛的說法是 Nginx 對於處理靜態文件更有優點,性能更好。其實若是是小網站,沒有靜態文件須要處理,只用 uWSGI 也是能夠的,但加上 Nginx 這一層,優點能夠很具體:

對於運維來講比較方便,若是服務器被某個 IP 攻擊,在 Nginx 配置文件黑名單中添加這個 IP 便可,若是隻用 uWSGI,那麼就須要在代碼中修改了。另外一方面,Nginx 是身經百戰的 Web 服務器了,在表現上 uWSGI 顯得更專業,好比說 uWSGI 在早期版本里是不支持 https 的,能夠說 Nginx 更安全。

nginx自己只能調用靜態文件, 它須要依賴網關協議文件來調用腳本.
uwsgi是nginx的標準模塊, 用於調用其它腳本.
修改nginx的配置文件conf/nginx.conf以指向uwsgi

location / { include uwsgi_params; uwsgi_pass 127.0.0.1:5000; root html; index index.html index.htm; } 

修改uwsgi文件, 配置腳本文件app_config.xml,
即運行的文件名以及應用名(nginx, uwsgi和app間須要經過socket進行交互)

<uwsgi> <pythonpath>/home/chenjiebin/web/flaskdemo</pythonpath> <module>flask</module> <callable>app</callable> <socket>127.0.0.1:5000</socket> <master/> <processes>4</processes> <memory-report/> </uwsgi> 

 

 

Nginx經常使用的幾個命令:
sudo service nginx start
sudo service nginx stop
sudo service nginx restart

1. uwsgi是uWSGI這個程序使用的協議。特色是比其餘協議都快。
2. 反向代理監聽某個端口,當有客戶端鏈接該端口,反向代理就會處理客戶端的請求。因此客戶端是主動的,反向代理是被動的。

 

 

部署多個應用

 

 一個Nginx中,能夠同時運行多個應用,不必定是Python的應用。咱們指望經過不一樣的路徑來路由不一樣的應用,所以就不能像上例那樣直接修改根目錄的配置。假設咱們但願經過」http://localhost/myapp」來訪問咱們的應用,首先要在Nginx的配置文件中,加入下面的內容:

 

location /myapp {
    include uwsgi_params;
    uwsgi_param SCRIPT_NAME /myapp;
    uwsgi_pass 127.0.0.1:3031;
}

 

這裏咱們定義了一個uWSGI參數」SCRIPT_NAME」,值爲應用的路徑」/myapp」。接下來,在uWSGI的啓動配置中,去掉」wsgi-file」項,並加上:

 

[uwsgi]
...
mount=/myapp=server.py
manage-script-name=true

 

「mount」參數表示將」/myapp」地址路由到」server.py」中,」manage-script-name」參數表示啓用以前在Nginx裏配置的」SCRIPT_NAME」參數。再次重啓Nginx和uWSGI,你就能夠經過」http://localhost/myapp」來訪問應用了。

 

補充內容

 

上面的全部例子中,咱們是經過」127.0.0.1:3031″Socket端口來鏈接Nginx和uWSGI的,其實咱們也能夠採用socket文件的方式,這樣能夠不用寫死端口。在uWSGI的啓動配置中,咱們要修改」socket」項:

 

[uwsgi]
socket=/tmp/uwsgi.sock
...

 

啓動uWSGI服務器後,它會自動建立一個」/tmp/uwsgi.sock」文件。而後讓咱們修改Nginx配置文件,將」uwsgi_pass」配置項改成文件:

location /myapp {
    include uwsgi_params;
    uwsgi_param SCRIPT_NAME /myapp;
    uwsgi_pass unix:/tmp/uwsgi.sock;
}

 

重啓Nginx服務器便可。這裏我開始一直沒跑通,研究了很久才發現,Nginx的用戶(默認的www-date:adm),必需要對該文件有讀寫的權限才行。由於運行uWSGI的用戶與運行Nginx的用戶不同,而」/tmp/uwsgi.sock」是由uWSGI的用戶建立的,致使Nginx沒有足夠的權限。若是朋友們也遇到一樣的問題,那就只能chmod了。

 

另外,仍是要提一下」.egg」包的解壓縮臨時目錄,咱們在介紹mod_wsgi的最後提到過,在uWSGI應用中也同樣,Linux上默認是在用戶主目錄下,好比」/home/bjhee/.python-eggs」。你能夠經過設置系統環境變量」PYTHON_EGG_CACHE」來改變它。

相關文章
相關標籤/搜索