在線上部署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項目的自有協議,主要特徵是採用二進制來存儲數據,
以前的協議都是存儲字符串,因此在存儲空間和解析速度上,都會優於字符串協議。python
附官方資料地址:http://uwsgi-docs.readthedocs.io/en/latest/FAQ.htmlmysql
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服務器。
centos7.3 nginx1.14.0 mysql 5.7 Django 2.0.6 django-cors-headers 2.2.0 future 0.16.0 mysqlclient 1.3.12 pip 10.0.1 PyMySQL 0.8.1 pytz 2018.4 setuptools 39.0.1 uWSGI 2.0.17 xlrd 1.1.0 xlwt 1.3.0
2.2.1 安裝依賴包程序員
# yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel python-devel
2.2.2 安裝pythonweb
(1)安裝python # wget https://www.python.org/ftp/python/3.6.5/Python-3.6.5.tgz # mkdir -p /usr/local/python365 # tar zxvf Python-3.6.5.tgz # cd Python-3.6.5 # ./configure --prefix=/usr/local/python365 # make # make install # ln -s /usr/local/python365/bin/python3 /usr/local/bin/python3 #配置python3的軟鏈接 # ln -s /usr/local/python365/bin/pip3 /usr/local/bin/pip3 #配置pip的軟鏈接 (2)驗證python版本 #python3 -V Python 3.6.5 (3 )驗證pip是否安裝 #pip3 -V pip 10.0.1 from /usr/local/python356/lib/python3.6/site-packages/pip (python 3.6)
2.2.3 安裝後續所須要的pip軟件包sql
(3)安裝所須要的包 #pip3 install ipython #安裝ipython方便調試 #pip3 install Django==2.0.6 #安裝Djiango #pip3 install django-cors-headers==2.2.0 #pip3 install future==0.16.0 #pip3 install mysqlclient==1.3.12 #pip3 install PyMySQL==0.8.1 #pip3 install pytz==2018.4 #pip3 install xlrd==1.1.0 #pip3 install xlwt==1.3.0
此處對nginx安裝描述不作太多的描述django
代碼目錄:/data/wwwroot/vim
日誌目錄:/data/wwwlogscentos
安裝目錄:/usr/local/nginx/
配置文件目錄:/usr/local/nginx/conf/vhost/
2.4.1 安裝測試
(1)安裝 # pip3 install uwsgi #ln -s /usr/local/python365/bin/uwsgi /usr/local/bin/uwsgi #創建軟連接 #uwsgi --version #檢查安裝成功 2.0.17 (2)測試 方法一: 建立test.py文件,添加以下代碼 # cat test.py def application(environ, start_response): status = '200 OK' output = 'Hello World! powerde by wsgi' response_headers = [('Content-type', 'text/plain'), ('Content-Length', str(len(output)))] start_response(status, response_headers) return [output] #執行以下代碼 uwsgi --http :8001 --wsgi-file test.py 瀏覽器訪問http://your-ip:8001輸出Hello World表示安裝正常 方法二: 如下ln命令爲了在終端中使用django-admin命令 ln -s /usr/local/python3/bin/django-admin /usr/bin/django-admin
建立一個測試的項目 django-admin startproject testProject cd testProject uwsgi --http :8000 --module testProject.wsgi 瀏覽器訪問http://your-ip:8000輸出It worked頁面表示安裝正常
2.4.2 配置
將代碼上傳到服務器上面/data/wwwroot下
(在django項目project目錄下(manage.py下)建立配置文件分兩種 ini 與xml這次安裝是經過uwsgi.ini的方式來進行配置的,也能夠經過xml的方式來進行配置)
# cd /data/wwwroot/huayun/huayun # vim uwsgi.ini [uwsgi] socket = 127.0.0.1:9090 chdir = /data/wwwroot/huayun module = huayun.wsgi master = true processes = 2 threads = 2 max-requests = 2000 vacuum = true daemonize = /data/wwwlogs/uwsgi.log post-buffering = 65535 buffer-size = 65535 harakiri-verbose = true harakiri = 300 uid = root pidfile = /var/run/uwsgi.pid
參數說明:
socket:指定監聽地址和端口
chdir:指定工程的絕對路徑,如Django的項目路徑
module:指定web應用的入口模塊,如Django項目下的wsgi.py接口文件
master:啓動主進程
processes:啓動進程數
threads:啓動線程數
max-requests:最大請求數
daemonize:指定uWSGI日誌文件路徑
stats:指定狀態查詢端口,如:127.0.0.1:9001
wsgi-file:指定啓動的文件
post-buffering:設置緩衝區
buffer-size:設置緩衝區文件大小
harakiri-verbose:設置超時true爲開啓
harakiri:設置超時時間
uid、gid:設置用戶和組
pidfile:指定啓動時的pid文件路徑
# vim /usr/lib/systemd/system/uwsgi.service [Unit] Description=uwsgi service After=network.target [Service] Type=forking PIDFile=/var/run/uwsgi.pid ExecStartPre=/usr/bin/rm -f /var/run/uwsgi.pid ExecStart=/usr/local/python365/bin/uwsgi --ini /data/wwwroot/huayun/huayun/uwsgi.ini ExecReload=/bin/kill -s HUP $MAINPID KillSignal=SIGQUIT TimeoutStopSec=5 KillMode=process PrivateTmp=true [Install] WantedBy=multi-user.target [root@host-10-0-100-111 system]# systemctl daemon-reload
#uwsgi --ini /data/wwwroot/huayun/huayunuwsgi.ini #啓動服務 能夠先直接用命令看項目是否可以跑成功
uwsgi --http :8000 --module huayun.wsgi
#ps -ef|grep "uwsgi" #查看進程 root 8616 1 0 18:45 ? 00:00:00 uwsgi --ini /data/wwwroot/huayun/huayun/uwsgi.ini root 8627 8616 0 18:45 ? 00:00:00 uwsgi --ini /data/wwwroot/huayun/huayun/uwsgi.ini root 8628 8616 0 18:45 ? 00:00:00 uwsgi --ini /data/wwwroot/huayun/huayun/uwsgi.ini
#netstat -lntp|grep "uwsgi" tcp 0 0 127.0.0.1:9090 0.0.0.0:* LISTEN 103596/uwsgi
配置nginx轉發uwsgi配置
# cd /usr/local/nginx/conf/vhost/
[root@host-10-0-100-135 vhost]# vim djiango.conf server { listen 8080; server_name localhost; charset utf-8; access_log /data/wwwlogs/huayun__access.log; error_log /data/wwwlogs/huayun_error.log; client_max_body_size 75M; location /static { alias /data/wwwroot/huayun/huayun/static; #配置靜態頁面地址 } location / { include /usr/local/nginx/conf/uwsgi_params; uwsgi_pass 127.0.0.1:9090; #轉發 } }
# systemctl restart nginx