Tengine + uwsgi + django平臺搭建


環境介紹:

[root@localhost opsdev]# nginx -v
Tengine version: Tengine/2.0.3 (nginx/1.4.7)
[root@localhost opsdev]# cat /etc/redhat-release 
CentOS release 6.4 (Final)
[root@localhost opsdev]# uwsgi -v
uwsgi: option requires an argument -- 'v'
getopt_long() error
[root@localhost opsdev]# uwsgi --version
2.0.9
[root@localhost opsdev]# django -v
-bash: django: command not found
[root@localhost opsdev]# python -c "import django;print (django.get_version())"
1.7.2
[root@localhost opsdev]#
[root@localhost opsdev]# python -V
Python 2.7.6


Come on~

1、安裝nginx

[root@localhost tmp]# yum install pcre pcre-devel -y
[root@localhost tmp]# tar xf tengine-2.0.3.tar.gz 
[root@localhost tmp]# cd tengine-2.0.3
[root@localhost tmp]# ./configure --prefix=/usr/local/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --with-http_stub_status_module --with-pcre --with-file-aio --with-http_flv_module --with-http_gzip_static_module --http-client-body-temp-path=/var/tmp/nginx/client/ --http-proxy-temp-path=/var/tmp/nginx/proxy/ --http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi --http-scgi-temp-path=/var/tmp/nginx/scgi
[root@localhost tmp]# make && make install
  • 相關選項


  • --prefix=/usr/local/nginx  
    安裝目錄
    --conf-path=/etc/nginx/nginx.conf
    配置文件存放位置  
    --error-log-path=/var/log/nginx/error.log  
    錯誤日誌存放位置
    --http-log-path=/var/log/nginx/access.log  
    訪問日誌存放的位置 
    --with-http_ssl_module  
    啓用SSL認證模塊
    --with-http_flv_module  
    啓用流媒體模塊
    --with-http_gzip_static_module
    啓用靜態頁面壓縮  
    --http-client-body-temp-path=/var/tmp/nginx/client/  
    HTTP包體存放的臨時目錄
    --http-proxy-temp-path=/var/tmp/nginx/proxy/  
    定義從後端服務器接收的臨時文件的存放路徑,可以爲臨時文件路徑定義至多三層子目錄的目錄樹
    --http-fastcgi-temp-path=/var/tmp/nginx/fcgi/  
    接收到FastCGI服務器數據,臨時存放於本地某目錄
    --with-pcre
    啓動正則表達式rewrite模塊
  • 添加nginx二進制路徑到PATH

[root@localhost tengine-2.0.3]# vim /etc/profile.d/nginx.sh
[root@localhost tengine-2.0.3]# cat /etc/profile.d/nginx.sh
export PATH=$PATH:/usr/local/nginx/sbin/
[root@localhost tengine-2.0.3]# source /etc/profile.d/nginx.sh
[root@localhost tengine-2.0.3]# nginx -v
Tengine version: Tengine/2.0.3 (nginx/1.4.7)
  • 導出頭文件

[root@localhost tengine-2.0.3]# ln -sv /usr/local/nginx/include/ /usr/include/nginx
`/usr/include/nginx' -> `/usr/local/nginx/include/'
  • 爲tengine提供Sysv服務腳本

#!/bin/sh
#
# nginx - this script starts and stops the nginx daemin
#
# chkconfig:   - 85 15 
# description:  Nginx is an HTTP(S) server, HTTP(S) reverse \
#               proxy and IMAP/POP3 proxy server
# processname: nginx
# config:      /usr/local/nginx/conf/nginx.conf
# pidfile:     /usr/local/nginx/logs/nginx.pid
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0
nginx="/usr/local/nginx/sbin/nginx"
prog=$(basename $nginx)
NGINX_CONF_FILE="/etc/nginx/nginx.conf"
lockfile=/var/lock/subsys/nginx
start() {
    [ -x $nginx ] || exit 5
    [ -f $NGINX_CONF_FILE ] || exit 6
    echo -n $"Starting $prog: "
    daemon $nginx -c $NGINX_CONF_FILE
    retval=$?
    echo
    [ $retval -eq 0 ] && touch $lockfile
    return $retval
}
stop() {
    echo -n $"Stopping $prog: "
    killproc $prog -QUIT
    retval=$?
    echo
    [ $retval -eq 0 ] && rm -f $lockfile
    return $retval
}
restart() {
    configtest || return $?
    stop
    start
}
reload() {
    configtest || return $?
    echo -n $"Reloading $prog: "
    killproc $nginx -HUP
    RETVAL=$?
    echo
}
force_reload() {
    restart
}
configtest() {
  $nginx -t -c $NGINX_CONF_FILE
}
rh_status() {
    status $prog
}
rh_status_q() {
    rh_status >/dev/null 2>&1
}
case "$1" in
    start)
        rh_status_q && exit 0
        $1
        ;;
    stop)
        rh_status_q || exit 0
        $1
        ;;
    restart|configtest)
        $1
        ;;
    reload)
        rh_status_q || exit 7
        $1
        ;;
    force-reload)
        force_reload
        ;;
    status)
        rh_status
        ;;
    condrestart|try-restart)
        rh_status_q || exit 0
            ;;
    *)
        echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
        exit 2
esac
  • 把該腳本放到/etc/init.d目錄下並賦予該腳本權限

[root@localhost tmp]# mv nginx /etc/init.d/nginx
[root@localhost tmp]# chmod +x /etc/init.d/nginx
  • 添加到開機啓動項並啓動服務

[root@localhost tmp]# chkconfig --add nginx
[root@localhost tmp]# chkconfig --level 35 nginx on
[root@localhost tmp]# chkconfig --list | grep nginx
nginx          	0:off	1:off	2:off	3:on	4:off	5:on	6:off
[root@localhost tmp]#
  • 啓動服務

[root@localhost init.d]# service nginx restart
the configuration file /etc/nginx/nginx.conf syntax is ok
configuration file /etc/nginx/nginx.conf test is successful
Stopping nginx:                                            [  OK  ]
Starting nginx:                                            [  OK  ]
[root@localhost init.d]# ss -tunlp | grep 80
tcp    LISTEN     0      128                    *:80                    *:*      users:(("nginx",7602,6),("nginx",7604,6))
[root@localhost init.d]#


2、升級Python

爲毛要升級Python呢,因爲django1.5之後的版本導入django core是使用推導式的,而推導式list是python2.7之後才支持的,so~


如果你建立django項目的時候出現如下報錯,請升級你的Python或降級django版本

  commands = {name: 'django.core' for name in find_commands(__path__[0])}
                                      ^
SyntaxError: invalid syntax
  • 我們這裏安裝python 2.7.5

[root@localhost tmp]# wget --no-check-certificate 
[root@localhost tmp]# tar -xzvf Python-2.7.5.tgz

[root@localhost tmp]# cd Python-2.7.5 

[root@localhost Python-2.7.5]# ./configure

[root@localhost Python-2.7.5]# make && make install

[root@localhost Python-2.7.5]# mv /usr/bin/python /usr/bin/python.bak

[root@localhost Python-2.7.5]# ln -s /usr/local/bin/python2.7 /usr/bin/python
  • 修復yum,修改後/usr/bin/yum第一行如下所示

[root@localhost tmp]# vim /usr/bin/yum

#!/usr/bin/python2.6
  • 安裝pip(如果你更新python之前安裝過pip,這個時候多半是不能用的,建議從官網從新下載安裝)

    常見報錯如下:

Traceback (most recent call last):
  File "/usr/bin/pelican-quickstart", line 5, in <module>
    from pkg_resources import load_entry_pointImportError: 
    No module named pkg_resources

    解決辦法:

重新安裝setuptools和pip即可解決

3、安裝django並創建項目

  • 安裝django

[root@localhost ~]# pip install django
  • 創建項目(在nginx定義的目錄下面)

[root@localhost www]# django-admin startproject opsdev

4、安裝uwsgi

  • 安裝uwsgi

[root@localhost opsdev]# pip install uwsgi
  • 測試

#test.py
def application(env,start_response):
    start_response('200 OK',[('Content-Type','text/html')])
    return ["hello world"]
  • 運行並查看結果

uwsgi:uwsgi --http :9090 --wsgi-file test.py


5、uwsgi配置django

  • 創建django_wsgi.py文件(和mange.py同級目錄)

[root@localhost opsdev]# ls
db.sqlite3         django_wsgi.py   manage.py  opsdev
django_wsgi.pyc  media      static
[root@localhost opsdev]# cat django_wsgi.py
#!/usr/bin/env python
# coding: utf-8

import os
import sys

# 將系統的編碼設置爲UTF8
#reload(sys)
#sys.setdefaultencoding('utf8')

#注意:"mysite.settings" 和項目文件夾對應。
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "opsdev.settings")

#from django.core.handlers.wsgi import WSGIHandler
#application = WSGIHandler()

# 上面兩行測試不對,然後從stackflow上面看到了下面兩行,測試ok
from django.core.wsgi import get_wsgi_application 
application = get_wsgi_application()
[root@localhost opsdev]#
  • 創建django_socket.xml文件(和mange.py同級目錄)

[root@localhost opsdev]# cat django_socket.xml 
<uwsgi>
    <socket>127.0.0.1:8077</socket> <!-- 和nginx中定義的要一致 -->
    <chdir>/www/opsdev</chdir>      <!-- 你django的項目目錄 -->
    <module>django_wsgi</module> <!-- 名稱爲剛纔上面定義的py文件名 -->
    <processes>4</processes> <!-- 進程數 --> 
    <daemonize>/var/log/uwsgi.log</daemonize>
</uwsgi>
[root@localhost opsdev]# ls
db.sqlite3         django_wsgi.py   manage.py  opsdev
django_socket.xml  django_wsgi.pyc  media      static
[root@localhost opsdev]#
  • 驗證是否能夠正常訪問

[root@localhost opsdev]# uwsgi --http :8000 --chdir /www/opsdev/ --wsgi-file django_wsgi.py
*** Starting uWSGI 2.0.9 (64bit) on [Thu Jan  8 12:21:15 2015] ***
compiled with version: 4.4.7 20120313 (Red Hat 4.4.7-11) on 07 January 2015 23:29:52
os: Linux-2.6.32-358.el6.x86_64 #1 SMP Fri Feb 22 00:31:26 UTC 2013
nodename: localhost.localdomain
  • 如果上面沒有出錯,就說明uwsgi和django結合完畢


6、配置nginx配置文件(其他未做更改)

       location / {
	    include uwsgi_params;
	    uwsgi_pass 127.0.0.1:8077;
        }

	location /static/ {
	    alias /www/opsdev/static/;
	    index index.html index.htm;
	}
	location /media/ {
	    alias /www/opsdev/media/;
	}

7、啓動測試

  • 啓動uwsgi

[root@localhost opsdev]# uwsgi -x django_socket.xml 
[uWSGI] parsing config file django_socket.xml
[root@localhost opsdev]#
  • 啓動nginx

[root@localhost opsdev]# service nginx start
Starting nginx:                                            [  OK  ]
[root@localhost opsdev]#
  • 查看進程

[root@localhost opsdev]# ss -tunlp 
Netid  State      Recv-Q Send-Q                                Local Address:Port                                  Peer Address:Port 
tcp    LISTEN     0      100                                       127.0.0.1:8077                                             *:*      users:(("uwsgi",25703,3),("uwsgi",25704,3),("uwsgi",25705,3),("uwsgi",25706,3))
tcp    LISTEN     0      128                                               *:80                                               *:*      users:(("nginx",26427,6),("nginx",26429,6))
  • 查看結果

wKioL1St-gzT3y2iAAG6FwoNvhQ637.jpg

常見FAQ:


  1. uwsgi: invalid option -- 'x' getopt_long() error

解決辦法:用“ yum install libxml*”即可解決。安裝uwsgi時看到 “xml = libxml2”就表示成功了

  1. “The translation infrastructure cannot be initialized before the ”
    django.core.exceptions.AppRegistryNotReady: The translation infrastructure cannot be initialized before the apps registry is ready. Check that you don’t make non-lazy gettext calls at import time.

解決辦法(修改django_wsgi.py):

原來:
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
改成:
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
重啓一下uwsgi。


  1. no python application found, check your startup logs for errors

    GET / => generated 21 bytes in 0 msecs (HTTP/1.1 500) 2 headers in 83 bytes (0 switches on core 0)

解決辦法:檢查django_wsgi.py配置文件,然後uwsgi單獨訪問下是否正常


還有很多東東要做,臥槽類。。。。

參考文檔:在此表示謝謝!

http://stackoverflow.com/questions/22148144/python-importerror-no-module-named-pkg-resources
https://github.com/imelucifer/MyNote/blob/master/django/django%2Buwsgi%2Bnginx%2Bcentos%E9%83%A8%E7%BD%B2.md
http://www.aaini.com/


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章