導論
WSGI是Web服務器網關接口。它是一個規範,描述了Web服務器如何與Web應用程序通訊,以及Web應用程序如何連接在一塊兒以處理一個請求,(接收請求,處理請求,響應請求) 基於wsgi運行的框架有bottle,DJango,Flask,用於解析動態HTTP請求 支持WSGI的服務器 wsgiref python自帶的web服務器 Gunicorn 用於linux的 python wsgi Http服務器,經常使用於各類django,flask結合部署服務器。 mode_wsgi 實現了Apache與wsgi應用程序的結合 uWSGI C語言開發,快速,自我修復,開發人員友好的WSGI服務器,用於Python Web應用程序的專業部署和開發。 在部署python程序web應用程序時,能夠根據性能的需求,選擇合適的wsgi server,不一樣的wsgi server區別在於併發支持上,有單線程,多進程,多線程,協程的區別,其功能仍是近似,無非是請求路由,執行對應的函數,返回處理結果。 Django部署 Django的主要部署平臺是 WSGI,這是用於Web服務器和應用程序的Python標準。 Django的 startproject管理命令設置一個簡單的默認WSGI配置,能夠根據須要爲您的項目進行調整,並指示任何符合WSGI的應用程序服務器使用。 application 使用WSGI部署的關鍵概念是應用程序服務器用於與代碼通訊的 application 可調用。它一般在服務器可訪問的Python模塊中做爲名爲 application 的對象提供。 startproject 命令建立包含這樣的 application 可調用的文件 <project_name>/wsgi.py. ,它被Django的開發服務器和生產WSGI部署使用。 WSGI服務器從其配置中獲取 application 可調用的路徑。 Django的內置服務器,即 runserver 命令,從 WSGI_APPLICATION 設置讀取它。
1 首先nginx 是對外的服務接口,外部瀏覽器經過url訪問nginx, 2nginx 接收到瀏覽器發送過來的http請求,將包進行解析,分析url,若是是靜態文件請求就直接訪問用戶給nginx配置的靜態文件目錄,直接返回用戶請求的靜態文件, 若是不是靜態文件,而是一個動態的請求,那麼nginx就將請求轉發給uwsgi,uwsgi 接收到請求以後將包進行處理,處理成wsgi能夠接受的格式,併發給wsgi,wsgi 根據請求調用應用程序的某個文件,某個文件的某個函數,最後處理完將返回值再次交給wsgi,wsgi將返回值進行打包,打包成uwsgi可以接收的格式,uwsgi接收wsgi 發送的請求,並轉發給nginx,nginx最終將返回值返回給瀏覽器。 3要知道第一級的nginx並非必須的,uwsgi徹底能夠完成整個的和瀏覽器交互的流程,可是要考慮到某些狀況 1 安全問題,程序不能直接被瀏覽器訪問到,而是經過nginx,nginx只開放某個接口,uwsgi自己是內網接口,這樣運維人員在nginx上加上安全性的限制,能夠達到保護程序的做用。 2負載均衡問題,一個uwsgi極可能不夠用,即便開了多個work也是不行,畢竟一臺機器的cpu和內存都是有限的,有了nginx作代理,一個nginx能夠代理多臺uwsgi完成uwsgi的負載均衡。 3靜態文件問題,用django或是uwsgi這種東西來負責靜態文件的處理是很浪費的行爲,並且他們自己對文件的處理也不如nginx好,因此整個靜態文件的處理都直接由nginx完成,靜態文件的訪問徹底不去通過uwsgi以及其後面的東西。
nginx官網html
http://nginx.org/en/
nginx有關uwsgi模塊介紹python
http://nginx.org/en/docs/http/ngx_http_uwsgi_module.html
我們都知道django是一個web框架,方便咱們快速開發web程序,http請求的動態數據就是由web框架來提供處理的。linux
前面也對nginx簡單的介紹了,本文將nginx、WSGI、uwsgi、uWSGI、django這幾個關係梳理一下。nginx
wsgi 全稱web server gateway interface,wsgi不是服務器,也不是python模塊,只是一種協議,描述web server如何和web application通訊的規則。
運行在wsgi上的web框架有bottle,flask,django
uwsgi 和wsgi同樣是通訊協議,是uWSGI服務器的單獨協議,用於定義傳輸信息的類型
uWSGI 是一個web服務器,實現了WSGI協議,uwsgi協議。a
nginx web服務器,更加安全,更好的處理處理靜態資源,緩存功能,負載均衡,所以nginx的強勁性能,配合uWSGI服務器會更加安全,性能有保障。
django 高級的python web框架,用於快速開發,解決web開發的大部分麻煩,程序員能夠更專一業務邏輯,無須從新造輪子
邏輯圖
web服務器程序員
傳統的c/s架構,請求的過程是 客戶端 > 服務器 服務器 > 客戶端 服務器就是:1.接收請求 2.處理請求 3.返回響應
web框架層web
HTTP的動態數據交給web框架,例如django遵循MTV模式處理請求。 HTTp協議使用url定位資源,urls.py將路由請求交給views視圖處理,而後返回一個結果,完成一次請求。 web框架使用者只須要處理業務的邏輯便可。
若是將一次通訊轉化爲「對話」的過程sql
Nginx:hello wsgi,我剛收到一個請求,你準備下而後讓django來處理吧apache
WSGI:好的nginx,我立刻設置環境變量,而後把請求交給djangodjango
Django:謝謝WSGI,我處理完請求立刻給你響應結果flask
WSGI:好的,我在等着
Django:搞定啦,麻煩wsgi吧響應結果傳遞給nginx
WSGI:太棒了,nginx,響應結果請收好,已經按照要求傳遞給你了
nginx:好滴。我把響應交給用戶。合做愉快
Django Nginx+uwsgi 安裝配置
在前面的章節中咱們使用 python manage.py runserver 來運行服務器。這隻適用測試環境中使用。
正式發佈的服務,須要一個能夠穩定而持續的服務器。
基礎開發環境配置
yum groupinstall "Development tools" yum install zlib-devel bzip2-devel pcre-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel
提早安裝好python3環境
virtualenv
請確保你的虛擬環境正常工做
http://www.javashuo.com/article/p-clzvtjtt-mw.html
安裝django1.11
pip3 install django==1.11.14
#建立django項目mysite
django-admin startproject mysite
#建立app01
python3 manage.py startapp app01
mysite/settings.py
#settings.py設置 ALLOWED_HOSTS = ['*'] install app01
mysite/urls.py
from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^hello_django/', views.hello), ]
app01/views.py
from django.shortcuts import render,HttpResponse # Create your views here. def hello(request): print('request is :',request) return HttpResponse('django is ok ')
安裝uWSGI
進入虛擬環境venv,安裝uwsgi (venv) [root@slave 192.168.11.64 /opt]$pip3 install uwsgi
檢查uwsgi版本
(venv) [root@slave 192.168.11.64 /opt]$uwsgi --version
2.0.17.1
#檢查uwsgi python版本
uwsgi --python-version
運行簡單的uWSGI
#啓動一個python uwsgi --http :9000 --wsgi-file test.py (注意http後面有個空格)
http :8000
: 使用http協議,端口8000wsgi-file test.py
: 加載指定的文件 test.py
uWsgi熱加載python程序
注意!!!!!!下面的啓動命令必須在切換到項目下執行,不然無效!!!!
在啓動命令後面加上參數 uwsgi --http :9000 --module dj1901.wsgi --py-autoreload=1 (後面參數不從新執行啓動命令,刷新瀏覽器生效)
(dj1901是本身django項目的名字)
.注意,此時你訪問admin發現項目丟失靜態文件,由於uwsgi不解析靜態文件配置
(怎樣收集靜態文件,看下面靜態文件相關配置)
想要收集靜態文件得用nginx,用啓用nginx的時候,http協議已經不能鏈接uwsgi,啓動得用socket協議
uwsgi --socket :9000 --module dj1901.wsgi --py-autoreload=1
上面運行django程序相關參數解釋:
#dj1901/wsgi.py 確保找到這個文件
uwsgi --http :9000 --module dj1901.wsgi
module dg1901.wsgi
: 加載指定的wsgi模塊 (.wsgi指的是wsgi.py 加. 把py 去掉了)
uwsgi配置文件
上面的啓動得在Django項目下,配置這個啓動文件爲了在其餘目錄下啓動方便,用下面ini命令啓動便可。
uwsgi支持ini、xml等多種配置方式,本文以 ini 爲例, 在/etc/目錄下新建uwsgi_nginx.ini,添加以下配置:
注意:等號左右不要空格
[uwsgi]
chdir=/root/Envs/c1902 #django項目所在的絕對路徑
module=c1902.wsgi #項目名字.wsgi ,和上面銜接,用的是相對路徑 home=/root/Envs/venv3 #虛擬環境所在的絕對路徑 master=true processes=1 socket=0.0.0.0:9000 vacuum=true
![](http://static.javashuo.com/static/loading.gif)
# mysite_uwsgi.ini file [uwsgi] # Django-related settings # the base directory (full path) chdir = /opt/mysite # Django's wsgi file module = mysite.wsgi # the virtualenv (full path) home = /opt/venv # process-related settings # master master = true # maximum number of worker processes processes = 1 # the socket (use the full path to be safe socket = 0.0.0.0:8000 # ... with appropriate permissions - may be needed # chmod-socket = 664 # clear environment on exit vacuum = true
指定配置文件啓動命令
uwsgi --ini /etc/uwsgi_nginx.ini (在任何目錄下均可以啓動了)
配置nginx結合uWSGI
配置nginx.conf
worker_processes 1; error_log logs/error.log; pid logs/nginx.pid; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log logs/access.log main; sendfile on; keepalive_timeout 65;
#nginx反向代理uwsgi
#nginx自帶ngx_http_uwsgi_module模塊,起到nginx和uwsgi交互做用
#經過uwsgi_pass設置服務器地址和協議,將動態請求轉發給uwsgi處理
server {
listen 80;
server_name localhost;
location / {
include /opt/nginx1-12/conf/uwsgi_params; #(uwsgi官網提供方法) uwsgi_pass 0.0.0.0:9000; #轉發參數,默認80端口轉到uwsgi的9000端口 root html; index index.html index.htm; }
#nginx處理靜態頁面資源
location /static { #F12,請求頭裏能夠看靜態資源走的路徑static,因此須要配置接口
alias /opt/static/django; #靜態文件放在哪裏,指明路徑
}
#nginx處理媒體資源
location /media{
alias /opt/nginx1-12/media;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
配置完啓動nginx
supervisor
supervisor 是基於 python 的任務管理工具,用來自動運行各類後臺任務,固然你也能直接利用 nohup 命令使任務自動後臺運行,但若是要重啓任務,每次都本身手動 kill 掉任務進程,這樣很繁瑣,並且一旦程序錯誤致使進程退出的話,系統也沒法自動重載任務。
這裏要配置基於virtualenv的supervisor
因爲supervisor在python3下沒法使用,所以只能用python2去下載!!!!!!
#注意此時已經退出虛擬環境了!!!!!
yum install python-setuptools
easy_install supervisor
或者 yum install -y epel-release && yum install -y supervisor(上述方法下載不了能夠用這個)
經過命令生成supervisor的配支文件
echo_supervisord_conf > /etc/supervisord.conf
而後再/etc/supervisord.conf末尾添加上以下代碼!!!!!!
![](http://static.javashuo.com/static/loading.gif)
supervisord.conf配置文件參數解釋 [program:xx]是被管理的進程配置參數,xx是進程的名稱 [program:xx] command=/opt/apache-tomcat-8.0.35/bin/catalina.sh run ; 程序啓動命令 autostart=true ; 在supervisord啓動的時候也自動啓動 startsecs=10 ; 啓動10秒後沒有異常退出,就表示進程正常啓動了,默認爲1秒 autorestart=true ; 程序退出後自動重啓,可選值:[unexpected,true,false],默認爲unexpected,表示進程意外殺死後才重啓 startretries=3 ; 啓動失敗自動重試次數,默認是3 user=tomcat ; 用哪一個用戶啓動進程,默認是root priority=999 ; 進程啓動優先級,默認999,值小的優先啓動 redirect_stderr=true ; 把stderr重定向到stdout,默認false stdout_logfile_maxbytes=20MB ; stdout 日誌文件大小,默認50MB stdout_logfile_backups = 20 ; stdout 日誌文件備份數,默認是10 ; stdout 日誌文件,須要注意當指定目錄不存在時沒法正常啓動,因此須要手動建立目錄(supervisord 會自動建立日誌文件) stdout_logfile=/opt/apache-tomcat-8.0.35/logs/catalina.out stopasgroup=false ;默認爲false,進程被殺死時,是否向這個進程組發送stop信號,包括子進程 killasgroup=false ;默認爲false,向進程組發送kill信號,包括子進程
uwsgi
[program:my] command=/root/Envs/venv1901/bin/uwsgi --ini /etc/uwsgi_nginx.ini #這裏是結合virtualenv的命令 和supervisor的精髓!!!!
#command= /root/Envs/venv1901/bin/uwsgi --uwsgi 0.0.0.0:8000 --chdir /root/Envs/myjd19 --home=/root/Envs/django14 --module myjd19.wsgi
#--home指的是虛擬環境目錄 --module找到 myjd19/wsgi.py
最後啓動supervisor,完成uWSGI啓動django,nginx反向代理
supervisord -c /etc/supervisord.conf #啓動supervisor
supervisorctl -c /etc/supervisord.conf restart my #重啓my項目
supervisorctl -c /etc/supervisord.conf [start|stop|restart][program|all]
supervisorctl能夠進入交互頁面,進行操做簡單
從新加載supervisor
1、添加好配置文件後
2、更新新的配置到supervisord
supervisorctl update
3、從新啓動配置中的全部程序
supervisorctl reload
4、啓動某個進程(program_name=你配置中寫的程序名稱)
supervisorctl start program_name
5、查看正在守候的進程
supervisorctl (進入交互模式)
6、中止某一進程 (program_name=你配置中寫的程序名稱)
supervisorctl stop program_name
7、重啓某一進程 (program_name=你配置中寫的程序名稱)
supervisorctl restart program_name
8、中止所有進程
supervisorctl stop all
注意:顯示用stop中止掉的進程,用reload或者update都不會自動重啓。
django的靜態文件與nginx配置
django項目下/settings.py文件最後進行配置
第一步:
STATIC_ROOT='/opt/static/django' #nginx.conf配置文件中須要配置相同靜態資源路徑 STATIC_URL = '/static/'
第二步:
配置完以後,切換到項目下,創建一個static目錄,收集靜態資源用,不然報錯!
python3 manage.py collectstatic
上述的參數STATIC_ROOT用在哪?
經過收集全部你使用的靜態文件保存到STATIC_ROOT!
STATIC_ROOT 文件夾 是用來將全部STATICFILES_DIRS中全部文件夾中的文件,以及各app中static中的文件都複製過來 # 把這些文件放到一塊兒是爲了用nginx等部署的時候更方便
(django以後會用到,能夠了解下) STATICFILES_DIRS=[ os.path.join(BASE_DIR,"static"), ]
參考文檔:http://uwsgi-docs-zh.readthedocs.io/zh_CN/latest/tutorials/Django_and_nginx.html
uwsgi熱加載:https://uwsgi-docs-zh.readthedocs.io/zh_CN/latest/Management.html