CentOS+uwsgi+django+nginx 環境部署及分析

寫在部署前

  在線上部署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,等等.
各種CGI簡介

 

瀏覽器請求一個頁面的流程

  1. 瀏覽器發送請求給服務器,包含請求頭和請求體
  2. 服務器解析請求頭和請求體
  3. 服務器根據請求信息來處理請求,生成返回內容
  4. 服務器生成響應頭和響應體
  5. 服務器返回響應給瀏覽器,瀏覽器顯示給用戶

  步驟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服務器。
Nginx相關簡介

 

正式安裝

#系統環境:
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
建立uwsgi的啓動腳本
# 配置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
相關文章
相關標籤/搜索