每一個框架或者應用都是爲了解決某些問題纔出現旦生的,沒有一個事物是能夠解決全部問題的。若是以爲某個框架或者應用使用很不方便,那麼頗有可能就是你沒有將其使用到正確的地方,沒有按開發者的設計初衷來使用它,當你將一個框架的優點使用到極致時必定是很是舒服和順手的一件事。但同時也有可能衍生另外一個問題,這個框架只解決了你的問題一,沒有解決問題2、三等等,所以,就出現了多個框架/應用相結合的狀況。好比Django + uWSGI + nginx。html
本人初學python,找了一些實例進行了一些操做,如下純屬目前的理解,若有誤差,歡迎修正。python
1、關於Django、uwsgi、nginx這三者關係的理解。nginx
Django是一個WEB框架。所謂WEB框架,那麼必定是搭建了一些模型,在安裝完框架後,能夠很方便的調用框架的方法,實現web功能。Django的特色在於MVC,模型--視圖--控制。關於MVC不一樣的框架有不一樣的定義,不用糾結去統一MVC的定義,只須要理解各個框架自身的設計的特色的優點。關於Django框架,M模型:指的的數據庫模型的管理(對於Django更多的在數據庫相關的應用程序開發上有一點的優點);V視圖:指的是如何根據業務需求來顯示M中的哪些數據,更可能是與業務相關;C控制:指的是用戶訪問的瀏覽器的地址與視圖的映射關係。因爲C比較簡單已經由Django封裝好了,基本上只用按正則表達示寫一些相似配置文件的東西便可。而人們說到MVC時通常會有一個表示層,即業務數據在頁面若是顯示,以表格仍是其它方式,表格的樣式如何等等,該層在Django中也可被稱爲T模板,被合併到V中。因此使用Django,咱們通常關心的是MTV的管理。web
既然Django其重點在於MVC的模架管理,雖然也可使用Django完成WEB服務器的功能(執行命令python manage.py runserver),可是僅僅是在測試環境中使用,對於要求穩定性和性能的生產環境,它沒法達到。所以須要加入uWSGI。wsgi是一種協議,僅僅是協議並未實現,而uwsgi也是一種協議,二者有所不一樣。而uWSGI就是使用python將wsgi與uwsgi進行實現的WEB服務器,Django + uWSGI其WEB服務器的功能要更優於Django自己自帶的web服務器。數據庫
那麼有了uWSGI爲何還須要nginx?由於nginx具有優秀的靜態內容處理能力,而後將動態內容轉發給uWSGI服務器,這樣能夠達到很好的客戶端響應。django
2、環境搭建。centos
一、安裝Django。瀏覽器
關於Django的使用網上資料不少,本人選擇了兩個比較合適的資料進行了實戰操做,以爲不錯。可參見」Django搭建及源碼分析(一)「,提到了搭建方法和,參考資料。下面進入本節主題。服務器
本人的系統環境centos6.0、python2.六、Django1.6,雖然都比較老了,可是不影響了解事物的本質的特色。繼續...app
二、安裝uWSGI。
Django環境的搭建與配置請參見"Django搭建及源碼分析(一)「,在保證Django能夠訪問以後,加入uWSGI。
使用pip install uwsgi
我安裝的是uwsgi 2.0.1版本。
三、驗證uWSGI是否安裝成功。
新建test.py文件,內容以下:
def application(env, start_response): start_response('200 OK', [('Content-Type','text/html')]) return "Hello World"
執行uwsgi --http :8000 --wsgi-file test.py
在瀏覽器內輸入:http://ip:8001,查看是否有"Hello World"輸出,若沒有輸出,請檢查你的安裝過程。
四、驗證Django+uWSGI是否鏈接成功。
uwsgi --http :8000 --wsgi-file /home/MyDjProj/MyDjProj/wsgi.py
將test.py修改成Django項目中生成的wsgi.py,經過瀏覽器訪問Django框架中的頁面,成功。則說明二者鏈接正常。
五、安裝nginx。
下載自已喜歡的nginx版本,我下的是當前最新穩定版nginx-1.8.0.tar.gz。
./configure --prefix=/usr/local/nginx-1.8 \ --with-http_stub_status_module \ --with-http_gzip_static_module
make && make install
六、配置uwsgi
uwsgi支持ini、xml等多種配置方式,本文以 ini 爲例在/etc下建立uwsgi8000.ini
[uwsgi] socket = 127.0.0.1:8000 master = true //主進程 vhost = true //多站模式 no-stie = true //多站模式時不設置入口模塊和文件 workers = 2 //子進程數 reload-mercy = 10 vacuum = true //退出、重啓時清理文件 max-requests = 1000 limit-as = 512 buffer-size = 30000 pidfile = /var/run/uwsgi8000.pid //pid文件,用於下面的腳本啓動、中止該進程 daemonize = /var/log/uwsgi8000.log //日誌文件 pythonpath = /usr/lib/python2.6/site-packages //同環境變量PYTHONPATH
七、配置nginx
找到nginx的安裝目錄(如:/usr/local/nginx-1.8/),打開conf/nginx.conf文件,修改server配置:
server { listen 80; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; location /{ include uwsgi_params; uwsgi_pass 127.0.0.1:8000; //必須和uwsgi中的設置一致 uwsgi_param UWSGI_SCRIPT MyDjProj.wsgi; //入口文件,即wsgi.py相對於Django項目根目錄的位置,「.」至關於一層目 uwsgi_param UWSGI_CHDIR /home/MyDjProj; //Django項目根目錄 index index.html index.htm; client_max_body_size 35m; }
八、測試Django + uwsgi + nginx
uwsgi --ini /etc/uwsgi8000.ini & /usr/local/nginx-1.8/sbin/nginx
在瀏覽器輸入:http://ip/,你就能夠看到django的"It work"了。http://ip/hello,能夠打開Django項目中,經過urlconf配置的hello子頁面的view視圖
3、遇到的問題。
一、在鏈接Django與uwsgi時(uwsgi --http :8000 --wsgi-file /home/MyDjProj/MyDjProj/wsgi.py),報出「ImportError: Could not import settings 'MyDjProj.settings' (Is it on sys.path? Is there an import error in the settings file?): No module named MyDjProj.settings」
能夠看出執行/home/MyDjProj/MyDjProj/wsgi.py時,在sys.path中沒法找到MyDjProj.settings,須要所/home/MyDjProj加入到sys.path中便可,加入方法有不少,在此我使用的是export PYTHONPATH=$PYTHONPATH:/home/MyDjProj,加入後,再訪問便可。
在鏈接Django、uwsgi和nginx時,sys.path不受環境變量PYTHONPATH的影響,也會自動將nginx配置中的項目根目錄加入到sys.path中,所以在後續步驟中此問題不影響三者鏈接。
二、在鏈接Django、uwsgi和nginx時,報出File "./MyDjProj/wsgi.py", line 17, in <module> from django.core.wsgi import get_wsgi_application ImportError: No module named django.core.wsgi
能夠看出在執行/home/MyDjProj/MyDjProj/wsgi.py時,在sys.path中沒法找到 django.core.wsgi,經過在MyDjProj/wsgi中加入sys.path的打印看出,sys.path中缺乏/usr/lib/python2.6/site-packages,緣由暫不清楚。
經過在uwsgi8000.ini中加入「pythonpath = /usr/lib/python2.6/site-packages」,從新鏈接成功。
三、遇到其它問題時,先判斷端口是否正常打開,使用netstat -plnt查看。
四、修改後配置後,最好關閉uwsgi及nginx後,從新鏈接。關閉方法:fuser -k 端口/tcp。如:fuser -k 80/tcp; fuser -k 8000/tcp
五、多查看日誌文件,文件中詳細的報錯信息,對於nginx的日誌,能夠經過在nginx.conf中配置error_log /var/log/nginx_error.log info;將出錯信息打印到該文件中便於定位。