uWSGI+django+nginx的工做原理流程與部署歷程

1、前言
獻給和我同樣懵懂中不斷汲取知識,進步的人們。php

霓虹閃爍,但人們真正須要的,只是一個能夠照亮前路的燭光css

2、必要的前提
2.1 準備知識html

django
一個基於python的開源web框架,請確保本身熟悉它的框架目錄結構。
1
uWSGI
一個基於自有的uwsgi協議、wsgi協議和http服務協議的web網關
1
nginx
經常使用高性能代理服務器
1
wsgi.py
django項目攜帶的一個wsgi接口文件
若是項目名叫destiny的話,此文件就位於[destiny/destiny/wsgi.py]
1
2
2.2 相關資料python

wsgi:一種實現python解析的通用接口標準/協議,是一種通用的接口標準或者接口協議,實現了python web程序與服務器之間交互的通用性。
利用它,web.py或bottle或者django等等的python web開發框架,就能夠輕鬆地部署在不一樣的web server上了;nginx

uwsgi:同WSGI同樣是一種通訊協議
uwsgi協議是一個uWSGI服務器自有的協議,它用於定義傳輸信息的類型,它與WSGI相比是兩樣東西。web

uWSGI :一種python web server或稱爲Server/Gateway
uWSGI相似tornadoweb或者flup,是一種python web server,uWSGI是實現了uwsgi和WSGI兩種協議的Web服務器,負責響應python 的web請求。
由於apache、nginx等,它們本身都沒有解析動態語言如php的功能,而是分派給其餘模塊來作,好比apache就能夠說內置了php模塊,讓人感受好像apache就支持php同樣。
uWSGI實現了wsgi協議、uwsgi協議、http等協議。 Nginx中HttpUwsgiModule的做用是與uWSGI服務器進行交換。apache

2.3 項目流程
其實網上不少教程,都是關於uwsgi+nginx部署django的,StackOverflow也有一些解決常見錯誤的方法,可是部署仍是容易出問題,新手難解決。
歸根究竟是本身不瞭解整個項目的流程。教程都只教方法,但爲何這樣部署,這樣部署有什麼好處,每一個組件都起什麼做用卻隻字不提。導致只要部署稍微有那麼一點不一樣,就無但是從了。
因此說,項目流程和每一個組件的用途纔是這次部署最重要的部分。django

首先客戶端請求服務資源,
nginx做爲直接對外的服務接口,接收到客戶端發送過來的http請求,會解包、分析,
若是是靜態文件請求就根據nginx配置的靜態文件目錄,返回請求的資源,
若是是動態的請求,nginx就經過配置文件,將請求傳遞給uWSGI;uWSGI 將接收到的包進行處理,並轉發給wsgi,
wsgi根據請求調用django工程的某個文件或函數,處理完後django將返回值交給wsgi,
wsgi將返回值進行打包,轉發給uWSGI,
uWSGI接收後轉發給nginx,nginx最終將返回值返回給客戶端(如瀏覽器)。
*注:不一樣的組件之間傳遞信息涉及到數據格式和協議的轉換
1
2
3
4
5
6
7
8
做用:
1. 第一級的nginx並非必須的,uwsgi徹底能夠完成整個的和瀏覽器交互的流程;
2. 在nginx上加上安全性或其餘的限制,能夠達到保護程序的做用;
3. uWSGI自己是內網接口,開啓多個work和processes可能也不夠用,而nginx能夠代理多臺uWSGI完成uWSGI的負載均衡;
4. django在debug=False下對靜態文件的處理能力不是很好,而用nginx來處理更加高效。瀏覽器

3、安裝與配置
首先,確保你已經安裝好了nginx並能夠正常使用。
其次,確保本身安裝完成了python,並已經完成了pip的安裝。若是沒有,請先安裝。
接着,別忘了確認本身項目所需的django已經完成安裝並正常工做。
沒有的話參考如下命令安裝django , 創建一個工程或利用已經寫好的工程,打開瀏覽器,輸入部署地址(如:http://127.0.0.1:8000/)(或http://內網ip:8000、或http://外網ip:8000)測試,確認是否可正常打開瀏覽。安全

安裝:sudo pip install django==1.10
測試:python manage.py runserver 0.0.0.0:8000
1
2
上面的工做都完成了,接着安裝uWSGI

sudo pip install uwsgi
1
測試uWSGI: 新建文件test.py,寫入如下內容

def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html')])
return "Hello World"
1
2
3
運行

sudo uwsgi --http 0.0.0.0:8000 --wsgi-file test.py
1
若是端口占用,使用

lsof -i :8000
1
列出佔用端口的程序的pid號,並使用如下命令殺掉全部佔用端口的程序

sudo kill -9 pid
1
而後瀏覽 http://127.0.0.1:8000(或http://內網ip:8000、或http://外網ip:8000)查看效果,有」Hello World」輸出即安裝成功。

下一步,創建工程單獨的nginx配置文件
首先確認本身準確的知道nginx的默認配置文件目錄(nginx.conf)的路徑,若是不清楚,請使用以下命令獲取:

nginx -t
1
大概會列出如下相似信息:

nginx: the configuration file /etc/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/conf/nginx.conf test is successful
1
2
裏面說明了nginx默認配置文件的路徑是:/etc/nginx/conf/nginx.conf;

而後,確保nginx.conf的同目錄下有uwsgi_params文件(/etc/nginx/conf/uwsgi_params),沒有的話根據連接獲取, 後面要用到。

在本身的工程目錄下,創建如destiny.conf(/wwwroot/destiny/destiny.conf)的配置文件;複製nginx.conf裏面所有的內容,所有寫入destiny.conf中。
而後按照下面寫的,把destiny.conf配置文件中的server段部分所有替換掉。

server {
listen 80;
server_name localhost;
charset utf-8;
access_log /wwwroot/destiny/nginx_access.log;
error_log /wwwroot/destiny/nginx_error.log;
client_max_body_size 75M;


location /static {
alias /wwwroot/destiny/destiny/static;
}

location / {
include /etc/nginx/conf/uwsgi_params;
uwsgi_pass 127.0.0.1:9090;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
其中的 listen 80表明服務器開放80端口;
location [目錄名]表明項目路徑的引導;
access_log 和error_log是定義nginx訪問日誌和錯誤日誌的存放路徑。
「location /static」中的」/static」是本身定義的項目引用靜態文件時,瀏覽器中顯示的靜態資源所在的根目錄名;這樣的話,用戶在瀏覽器中查看到的全部image、css或js資源都是處在http://127.0.0.1/static下的。
django靜態文件的絕對路徑是根據本身的實際狀況來肯定的,通常在本身的django的app名/static目錄下,或本身python manage.py collectstatic後的路徑下。像個人是在/wwwroot/destiny/destiny/static根目錄下。
「location /」是指訪問項目根目錄時,nginx要作的事。其中須要指定 uwsgi_params文件的絕對路徑,上面已經提到了;若是還有media文件之類的靜態目錄,仿照static的寫法,本身補充。
127.0.0.1:9090是指uWSGI綁定的監聽地址,這裏使用了9090端口。
須要注意的是,請確認本身django的靜態文件目錄全部者是www用戶,若是不是,請用如下命令更改靜態目錄權限歸屬者:

sudo chown -R www:www /wwwroot/destiny/destiny/static
1
下面接着創建uWSGI的配置文件,在本身工程目錄下建立uwsgi.ini文件,寫入如下內容

[uwsgi]
socket = 127.0.0.1:9090
chdir=/wwwroot/destiny
module=destiny.wsgi
master = true
processes=2
threads=2
max-requests=2000
chmod-socket=664
vacuum=true
daemonize = /wwwroot/destiny/uwsgi.log
1
2
3
4
5
6
7
8
9
10
11
其中的socket字段值」127.0.0.1:9090」必需要和上面寫的density.conf配置文件中的uWSGI監聽地址徹底同樣;
chdir指本身工程的絕對路徑;
module指的是wsgi.py在本身工程中的相對路徑,」.」指代一層目錄;個人django工程的wsgi.py文件是在」/wwwroot/destiny/destiny/wsgi.py」,因此寫成destiny.wsgi;
daemonize指定uWSGI日誌的存儲路徑。

好了,如今理一下路徑:

工程路徑: /wwwroot/destiny
工程靜態文件路徑: /wwwroot/destiny/destiny/static
wsgi.py的路徑: /wwwroot/destiny/destiny/wsgi.py
uwsgi.ini的路徑: /wwwroot/destiny/uwsgi.ini
uwsgi日誌路徑: /wwwroot/destiny/uwsgi.log
destiny.conf的路徑: /wwwroot/destiny/destiny.conf
uwsgi_params的路徑: /etc/nginx/conf/uwsgi_params
nginx訪問日誌路徑: /wwwroot/destiny/nginx_access.log
nginx錯誤日誌路徑: /wwwroot/destiny/nginx_error.log
1
2
3
4
5
6
7
8
9
能夠發現,我幾乎把全部有關工程的配置文件和日誌文件都放在工程目錄下了,方便後期維護與查錯。
啓動uWSGI

sudo uwsgi --ini /wwwroot/destiny/destiny.ini
1
啓動nginx
在這以前,咱們要先去nginx配置文件的根目錄拷貝mime.types(/etc/nginx/conf/mime.types)到工程目錄(/wwwroot/destiny/mime.types),和destiny.conf放在一塊兒。
不然用配置文件啓動nginx會報錯:

nginx: [emerg] open() "/**/**/**/mime.types" failed (2: No such file or directory)
1
固然,若是不想拷貝mime.types文件,也能夠將配置文件中「include mime.types;」一項,改爲絕對路徑「include /etc/nginx/conf/mime.types;」
若是nginx已經開啓,先關閉nginx(service nginx stop或nginx -s stop),再執行如下命令:

nginx -c /wwwroot/destiny/destiny.conf
1
這裏的-c 表示加載配置文件啓動

4、後記
到這裏,工做基本就作完了,能夠打開瀏覽器,輸入本身項目的IP地址,如http://127.0.0.1/查看效果了。

 

若是啓動時就報錯,查看終端信息,解決錯誤。
若是終端沒有報錯,可是瀏覽時出現500、502等錯誤,就去項目目錄查看nginx日誌和uWSGI日誌,解決錯誤。

本身在部署時,遇到不少坑,網上的教程大多附帶virtualenv和supervisor的部署,可是連最基本的部署都說不明白,部署出來的東西性能再好也沒指導意義。基於本身踩坑脫坑的過程,寫下此文。

正如以上所說,我只是用單獨的一個conf文件,在nginx上部署了一個工程,沒有說明部署多個工程的問題;也沒有使用virtualenv開發環境、使用supervisor來管理進程等。請根據我的愛好和須要去實踐擴展。

相關文章
相關標籤/搜索