在線上部署django項目時,比較成熟的方案是:nginx + uWSGI + Django。 nginx和Django 都比較熟悉了,uWSGI是什麼呢?WSGI是一個協議,python用於web開發的協議,uWSGI則是一個程序,充當WEB服務器或者中間件。當Nginsx+uWSGI+Django一塊兒使用時,uWSGI就是個中間件,若是直接用django+uWSGI時,uWSGI就是個WEB服務器。html
說下WEB協議出現的順序: CGI --> FCGI --> WSGI --> uwsgi。
CGI是最先的協議,而後FCGI顧名思義就是比CGI更快,WSGI是Python專用的協議,uwsgi比FCGI和WSGI都快,是uWSGI項目的自有協議,主要特徵是採用二進制來存儲數據,
以前的協議都是存儲字符串,因此在存儲空間和解析速度上,都會優於字符串協議。附官方資料地址:http://uwsgi-docs.readthedocs.io/en/latest/FAQ.htmlpython
CGI = Common Gateway Interface,通用網關接口 顧名思義,它是一種接口規範。該規範詳細定義了Web服務器中運行的服務器代理程序,怎樣獲取及返回網頁生成過程當中,服務器環境上下文和HTTP協議中的參數名稱, 如你們所熟知的:REQUEST_METHOD,QUERY_STRING,CONTENT_TYPE等等。絕大部分的Web服務器程序,是以腳本的形式代理接受並處理HTTP請求,返回HTTP頁面或響應。 這些腳本程序,就是你們所熟知的PHP、ASP、JSP等等。 FCGI = Fast CGI 它實際上是CGI在具體實現中的的一個變種。其設計思路是,經過減小CGI代理程序和Web宿主服務程序的通訊開銷,從而達到提升Web服務性能的最終目的。 因而可知,FCGI在規範上跟CGI並無不一樣, 只是具體實現方式上有所改進: CGI的作法是,對於每一個HTTP請求,Web宿主服務程序都創建新的進程以調用服務器腳本,響應該請求;大量HTTP請求時,服務器頻繁建立進程會影響服務器性能。 FCGI的作法是,創建一個獨立的FCGI服務程序進程,和Web宿主服務程序進程通訊,FCGI服務進程被一旦啓動後,本身分配資源、建立線程響應HTTP請求、並決定自身生命週期, 從而大大下降了系統爲了建立進程而作出的資源開銷。FCGI還支持分佈式,也就是WEB服務器和應用程序能夠再不通的機器上。 現代流行的Web服務器程序,如PHP、ASP.Net,基本都是FCGI的實現。 SCGI = Simple CGI 它是FCGI在精簡數據協議和響應過程後的產物。其設計目的是爲了適應愈來愈多基於AJAX或REST的HTTP請求,而作出更快更簡潔的應答。 而且SCGI約定,當服務器返回對一個HTTP協議請求響應後,馬上關閉該HTTP鏈接。因此不難看出,SCGI更加適合於廣泛意義上SOA所提倡的「請求-忘記」這種通訊模式。 WSGI = Web Server Gateway Interface 此協議是Python語言的專利,它定義了一組在Web服務宿主程序和HTTP響應代理程序之間通訊的廣泛適用的接口。 它的產生是由於Python程序員注意到,對於Web框架和Web宿主服務器程序間,有嚴重的耦合性,好比說,某些框架是針對Apache的mod_python設計的。 因而,WSGI就定義了一套很是低級別的接口。常見的Python Web框架都實現了這個協議:如 CherryPy, Django, web.py, web2py, TurboGears, Tornado, Pylons, BlueBream, Google App Engine[dubious – discuss], Trac, Flask, Pyramid,等等.
步驟1,2,4,5在全部網站的請求中都是同樣的,只有步驟3是不固定的。因此把固定的4個步驟抽象出來,讓開發者只關注步驟3,能夠提升開發效率。
WSGI,全稱 Web Server Gateway Interface, 是python專用的協議,其餘語言沒有。用於處理WEB服務器和應用程序APP的交互信息。不少WEB框架
都有自帶的WSGI服務器,不過性能並不理想,只能用於測試用途。nginx
# nginx 相關 (1)正向代理:瀏覽器主動請求代理服務器,代理服務器轉發請求到對應的目標服務器。 (2)反向代理:部署在WEB服務器上,代理全部外部網絡的訪問,瀏覽器訪問服務器,必須通過這個代理,是被動的。 正向代理的主動方是客戶端,反向代理的主動方是WEB服務器。 反向代理的做用: (1)安全,客戶端對Web服務器的訪問須要先通過反向代理服務器。這樣能夠防止外部程序對Web服務器的直接攻擊。 (2)負載均衡,反向代理服務器能夠根據Web服務器的負載狀況,動態地把HTTP請求交給不一樣的Web服務器來處理,前提是要有多個Web服務器。 (3)提高Web服務器的IO性能。一個HTTP請求的數據,從客戶端傳輸給服務器,是須要時間的,例如N秒,若是直接傳給Web服務器,Web服務器就須要讓一個進程阻塞N秒,來接收IO, 這樣會下降Web服務器的性能。若是使用反向代理服務器,先讓反向代理服務器接收完整個HTTP請求,再把請求發給Web服務器,就能提高Web服務器的性能。還有一些靜態文件的請求, 能夠直接交給反向代理來處理,不須要通過Web服務器。
#系統環境: CentOS 7 nginx Django1.9 python3.6 uwsgi
# 安裝依賴包 yum install zlib-devel bzip2-devel pcre-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel python-pip -y # 安裝uwsgi pip install uwsgi # 查看版本 uwsgi --version
# 測試uwsgi是否正常,實現一個最簡單的服務器 # vim test.py #!/usr/bin/python env # coding: utf-8 def application(env, start_response): start_response('200 OK', [{'Contetn-Type', 'text/html'}]) return "hello world" # 解釋: # env參數是一個字典對象,保存HTTP請求的信息,如URL路徑,域名,請求頭,請求參數等 # start_response 參數是一個函數,用於向wsgiref提供響應頭的設置,只能調用一次。 # 在終端運行 uwsgi --http :8080 --wsgi-file test.py # 瀏覽器輸入 http://127.0.0.1:8080 , 若是返回hello world 則正確,不是的話,請檢查上面步驟。
# 安裝django 和 nginx pip install Django==1.9 yum install nginx -y
# 配置uwsgi vim /etc/uwsgi.ini [uwsgi] socket = 127.0.0.1:10000 // 運行端口號 chdir = /data/OPS/superops/ // django項目絕對路徑 wsgi-file = superops/wsgi.py // django的wsgi文件 master = true // 主進程 vhost = true // 多站模式 no-stie = true // 多站模式時不設置入口模塊和文件 workers = 2 // 子進程數 reload-mercy = 10 vacuum = true // 退出,重啓時清理文件 max-requests = 1000 limit-as = 512 buffer-sizi = 30000 pidfile = /var/run/uwsgi.pid // pid文件,用於下面的腳本啓動,中止該進程 daemonize = /var/log/uwsgi.log // 日誌文件,這個日誌會記錄django運行日誌 # 附:uWSGI參考資料:http://www.cnblogs.com/zhouej/archive/2012/03/25/2379646.html
# 啓動uwsgi uwsgi /etc/uwsgi.ini
# cat /etc/init.d/uwsgi DESC="uwsgi daemon" NAME=uwsgi DAEMON=/usr/bin/uwsgi CONFIGFILE=/etc/$NAME.ini PIDFILE=/var/run/$NAME.pid SCRIPTNAME=/etc/init.d/$NAME set -e [ -x "$DAEMON" ] || exit 0 do_start() { $DAEMON $CONFIGFILE || echo -n "uwsgi running" } do_stop() { $DAEMON --stop $PIDFILE || echo -n "uwsgi not running" rm -f $PIDFILE echo "$DAEMON STOPED." } do_reload() { $DAEMON --reload $PIDFILE || echo -n "uwsgi can't reload" } do_status() { ps aux|grep $DAEMON } case "$1" in status) echo -en "Status $NAME: \n" do_status ;; start) echo -en "Starting $NAME: \n" do_start ;; stop) echo -en "Stopping $NAME: \n" do_stop ;; reload|graceful) echo -en "Reloading $NAME: \n" do_reload ;; *) echo "Usage: $SCRIPTNAME {start|stop|reload}" >&2 exit 3 ;; esac exit 0
# 配置nginx server { listen 8888; // 外網訪問端口 listen [::]:8888; server_name _; root /usr/share/nginx/html; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { include uwsgi_params; uwsgi_pass 127.0.0.1:10000; // 必須和uwsgi.ini配置的端口一致 uwsgi_param UWSGI_SCRIPT superops.wsgi; // 入口文件, superops是項目名稱 uwsgi_param UWSGI_CHDIR /data/OPS/superops; // 項目根目錄,這個路徑是有manage.py的那一層 index index.html index.htm; client_max_body_size 35m; } location /static/ { alias /data/OPS/superops/static/; // 有時候會發現訪問網站的時候加載不到資源(404)在這裏聲明下。 }
# 測試總體 /etc/init.d/uwsgi start systemctl start nginx 在瀏覽器中輸入http://127.0.0.1:8888 就能夠正常訪問django 項目了
# 多站配置 # uwsgi:也就是使用多個uwsgi服務的方法來實現多個站點,建立多個/etc/uwsgi01.ini並修改文件對應的端口號 # nginx: 在配置文件中再配置一個server,設置不一樣的端口,並指向uwsgi