為什么需要uWSGI?
在生產(chǎn)環(huán)境中部署Python Web項目時,uWSGI負責處理Nginx轉(zhuǎn)發(fā)的動態(tài)請求,并與我們的Python應用程序溝通,同時將應用程序返回的響應數(shù)據(jù)傳遞給Nginx。
。
客戶端 <-> Nginx <-> uWSGI <-> Python應用程序(Django, Flask)
或許你要問了,Nginx本身就是Web服務器,我們?yōu)槭裁催€需要uWSGI這個Web服務器呢?
Django不是自帶runserver服務器?
Flask不是自帶Werkzeug嗎?
答案是Nginx處理靜態(tài)文件非常優(yōu)秀,卻不能直接與我們的Python Web應用程序進行交互。Django和Flask本身是Web框架,并不是Web服務器,它們自帶的runserver和Werkzeug也僅僅用于開發(fā)測試環(huán)境,生產(chǎn)環(huán)境中處理并發(fā)的能力太弱
為了解決Web 服務器與應用程序之間的交互問題,就出現(xiàn)了Web 服務器與應用程序之間交互的規(guī)范。最早出現(xiàn)的是CGI,后來又出現(xiàn)了改進 CGI 性能的FasgCGI,Java 專用的 Servlet 規(guī)范。在Python領域,最知名的就是WSGI規(guī)范了。
WSGI 全稱是 Web Server Gateway Interface,
也就是 Web 服務器網(wǎng)關接口,是一個web服務器(如uWSGI服務器)與web應用(如用Django或Flask框架寫的程序)通信的一種規(guī)范。WSGI包含了很多自有協(xié)議,其中一個是uwsgi,它用于定義傳輸信息的類型。
現(xiàn)在你清楚uWSGI, WSGI和uwsgi的區(qū)別了嗎?
- uWSGI是Python Web服務器,實現(xiàn)了WSGI通信規(guī)范和uwsgi協(xié)議;
- WSGI全名Web Server Gateway Interface,是一個Web服務器(如uWSGI服務器)與web應用(如用Django或Flask框架寫的程序)通信的一種規(guī)范;
- uwsgi是WSGI通信規(guī)范中的一種自有協(xié)議。
uWSGI常用配置
uWSGI常用配置選項如下所示,稍加修改(項目名,項目根目錄)即可部署大部分Python Web項目。
[uwsgi] uid=www-data # Ubuntu系統(tǒng)下默認用戶名 gid=www-data # Ubuntu系統(tǒng)下默認用戶組 project=mysite1 # 項目名 base = /home/user1 # 項目根目錄 home = %(base)/Env/%(project) # 設置項目虛擬環(huán)境,Docker部署時不需要 chdir=%(base)/%(project) # 設置工作目錄 module=%(project).wsgi:application # wsgi文件位置 master=True # 主進程 processes=2 # 同時進行的進程數(shù),一般 # 以下uwsgi與nginx通信手段3選一即可 # 選項1, 使用unix socket與nginx通信,僅限于uwsgi和nginx在同一主機上情形 # Nginx配置中uwsgi_pass應指向同一socket文件 socket=/run/uwsgi/%(project).sock # 選項2,使用TCP socket與nginx通信 # Nginx配置中uwsgi_pass應指向uWSGI服務器IP和端口 # socket=0.0.0.0:8000 或則 socket=:8000 # 選項3,使用http協(xié)議與nginx通信 # Nginx配置中proxy_pass應指向uWSGI服務器一IP和端口 # http=0.0.0.0:8000 # socket權限設置 chown-socket=%(uid):www-data chmod-socket=664 # 進程文件 pidfile=/tmp/%(project)-master.pid # 以后臺守護進程運行,并將log日志存于temp文件夾。 daemonize=/var/log/uwsgi/%(project).log # 服務停止時,自動移除unix socket和pid文件 vacuum=True # 為每個工作進程設置請求數(shù)的上限。當處理的請求總數(shù)超過這個量,進程回收重啟。 max-requests=5000 # 當一個請求花費的時間超過這個時間,那么這個請求都會被丟棄。 harakiri=60 #當一個請求被harakiri殺掉會輸出一條日志 harakiri-verbose=true # uWsgi默認的buffersize為4096,如果請求數(shù)據(jù)超過這個量會報錯。這里設置為64k buffer-size=65536 # 如果http請求體的大小超過指定的限制,打開http body緩沖,這里為64k post-buffering=65536 #開啟內(nèi)存使用情況報告 memory-report=true #設置平滑的重啟(直到處理完接收到的請求)的長等待時間(秒) reload-mercy=10 #設置工作進程使用虛擬內(nèi)存超過多少MB就回收重啟 reload-on-as=1024
注意:uWSGI和Nginx之間有3種通信方式, unix socket,TCP socket和http。Nginx的配置必須與uwsgi配置保持一致。
# 選項1, 使用unix socket與nginx通信 # 僅限于uwsgi和nginx在同一主機上情形 # Nginx配置中uwsgi_pass應指向同一socket文件地址 socket=/run/uwsgi/%(project).sock # 選項2,使用TCP socket與nginx通信 # Nginx配置中uwsgi_pass應指向uWSGI服務器IP和端口 socket==0.0.0.0:8000 或則 socket=:8000 # 選項3,使用http協(xié)議與nginx通信 # Nginx配置中proxy_pass應指向uWSGI服務器IP和端口 http==0.0.0.0:8000
如果你的nginx與uwsgi在同一臺服務器上,優(yōu)先使用本地機器的unix socket進行通信,這樣速度更快。此時nginx的配置文件如下所示:
location / { include /etc/nginx/uwsgi_params; uwsgi_pass unix:/run/uwsgi/project.sock; }
如果nginx與uwsgi不在同一臺服務器上,兩者使用TCP socket通信時,nginx可使用如下配置:
location / { include /etc/nginx/uwsgi_params; uwsgi_pass uWSGI_SERVER_IP:8000; }
如果nginx與uwsgi不在同一臺服務器上,兩者使用http協(xié)議進行通信,nginx配置應修改如下:
location / { # 注意:proxy_pass后面http必不可少哦! proxy_pass http://uWSGI_SERVER_IP:8000; }