Django + uWSGI + Nginx 實現生產環境部署

1、Uwsgi 是啥?javascript

WSGI(Web Server Gateway Interface),是一種Web服務器網關接口。它是一個Web服務器(如nginx,uWSGI等服務器)與web應用(如用Flask框架寫的程序)通訊的一種規範。php

uWSGI 是一個快速的、純C語言開發的、自維護的、對開發者友好的 WSGI 服務器,旨在提供專業的 Python web應用發佈和開發。可以使用 C/C++/Objective-C 來爲 uWSGI 編寫插件。css

要注意 WSGI / uwsgi / uWSGI 這三個概念的區分。html

  1. WSGI是一種Web服務器網關接口。它是一個Web服務器(如nginx,uWSGI等服務器)與web應用(如用Flask框架寫的程序)通訊的一種規範。
  2. uwsgi是一種線路協議而不是通訊協議,在此經常使用於在uWSGI服務器與其餘網絡服務器的數據通訊。
  3. 而uWSGI是實現了uwsgi和WSGI兩種協議的Web服務器。
  4. uwsgi協議是一個uWSGI服務器自有的協議,它用於定義傳輸信息的類型(type of information),每個uwsgi packet前4byte爲傳輸信息類型描述,它與WSGI相比是兩樣東西。

uWSGI的主要特色以下java

  1. 超快的性能
  2. 低內存佔用(實測爲apache2的mod_wsgi的一半左右)
  3. 多app管理(終於不用左思右想下個app用哪一個端口比較好了-.-)
  4. 詳盡的日誌功能(能夠用來分析app性能和瓶頸)
  5. 高度可定製(內存大小限制,服務必定次數後重啓等)
  6. 處理靜態請求不太好

2、Nginx是啥?python

Nginx(發音同engine x)是一個網頁服務器,它能反向代理HTTP, HTTPS, SMTP, POP3, IMAP的協議連接,以及一個負載均衡器和一個HTTP緩存。其特色是佔有內存少,併發能力強。mysql

3、比較好使的框架結構linux

 

 

 4、環境搭建nginx

a、Linux服務器一臺web

[root@web01 ~]# cat /etc/redhat-release 
CentOS release 6.6 (Final)
[root@web01 ~]# uname -r
2.6.32-504.el6.x86_64
系統和內核版本

b、安裝Python和Django相關的軟件和工具包

  1. 安裝setuptools
    [root@django tools]# yum install pcre pcre-devel openssl openssl-devel zlib bzip2-devel -y
    
    [root@django tools]# ll 
    -rw-r--r-- 1 root root 641502 3月   2 18:50 setuptools-19.6.tar.gz
    
    [root@django tools]# tar xf setuptools-19.6
    
    [root@django tools]# cd setuptools-19.6
    
    [root@django tools]#python setup.py install
    
    [root@django tools]#cd ..
    
    ##################################################################
    
    #nginx模塊
    
    pcre pcre-devel  #perl語言兼容正則表達式,用來作Nginx的HTTP Rewrite 模塊
    
    bzip2-devel   ·#提供壓縮功能
    
    openssl openssl-devel  #https加密模塊
    
    ###################################################################
    
    zlib #在編譯python3的時候,加載setuptools的時候會報錯,因此這裏提早處理啦!
    源碼安裝setuptools
  2. 安裝pip
    [root@django tools]# ll 
    -rw-r--r-- 1 root root 1197370 3月   2 13:30 pip-9.0.1.tar.gz
    
    [root@django tools]# tar xf pip-9.0.1.tar.gz 
    
    [root@django tools]# cd pip-9.0.1
    
    [root@django pip-9.0.1]# python setup.py install
    
    [root@django pip-9.0.1]# cd ..
    
    #配置環境變量:
    
    [root@django bin]# vi /etc/profile
    export PATH="/usr/local/python3/bin:$PATH"
    
      [root@django bin]# tail -1 /etc/profile
      export PATH="/usr/local/python3/bin:$PATH"
      [root@django bin]# source /etc/profile
      #查看幫助
      [root@django bin]# pip3  或 pip
    升級到最新的pip
  3. 安裝sqlite3
    方法一:
    yum install sqlite-devel
    
    或
    
    方法二:
    
    軟件下載官網:http://www.sqlite.org
    
    [root@django tools]# ll
    -rw-r--r-- 1 root root 2515143 3月   2 13:33 sqlite-autoconf-3170000.tar.gz
    
    [root@django tools]# tar xf sqlite-autoconf-3170000.tar.gz
    
    [root@django tools]# cd sqlite-autoconf-3170000
    
    [root@django tools]# ./configure
    
    [root@django tools]#make && make install
    安裝sqlite
  4. 升級到Python3
    方法一:
    
    升級爲python3.5版本步驟
    root@template ~]# cd /home/oldboy/tools/
    
    #下載python-3.5.2
    [root@template tools]# wget https://www.python.org/ftp/python/3.5.2/Python-3.5.2.tgz
    
    [root@template tools]# ll
    總用量 20104
    -rw-r--r--  1 root root 20566643 6月  26 05:47 Python-3.5.2.tgz
    
    #解壓到下載目錄
    [root@template tools]# tar zxvf Python-3.5.2.tgz 
    
    #進入解壓後的文件夾
    [root@template tools]# cd Python-3.5.2
    
    #在編譯前先在/usr/local建一個文件夾python3(做爲python的安裝路徑,以避免覆蓋老的版本)
    [root@template Python-3.5.2]# mkdir /usr/local/python3
    
    #開始編譯安裝
    [root@template Python-3.5.2]#  ./configure --prefix=/usr/local/python3
    
    [root@template Python-3.5.2]# make && make install
    
    此時沒有覆蓋老版本,再將原來/usr/bin/python連接改成別的名字
    [root@template Python-3.5.2]# mv /usr/bin/python /usr/bin/python_old
    
    #再創建新版本python的軟連接
    [root@template Python-3.5.2]# ln -s /usr/local/python3/bin/python3 /usr/bin/python
    
    #就會顯示出python的新版本信息
    [root@template Python-3.5.2]# python
    Python 3.5.2 (default, Aug  2 2016, 11:35:06) 
    [GCC 4.4.7 20120313 (Red Hat 4.4.7-11)] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> exit()     #<----退出python
    
    PS:若是不創建新安裝路徑python3,而是直接默認安裝,則安裝後的新python應該會覆蓋linux下自帶的老版本。固然若是還想保留原來的版本,那麼這種方法最好不過了。
    
    注意事項:
    這種方法雖然能安裝成功,但會致使yum不能正常使用。
    
    解決方法:
    [root@template tools]# cp /usr/bin/yum /usr/bin/yum.backup_2016-08-02
    
    修改第一行參數
    vi /usr/bin/yum   
    把  #!/usr/bin/python    修改成:/usr/bin/python_old  
    或
    把  #!/usr/bin/python    修改成:/usr/bin/python2.6
    
    #查看版本
    [root@template Python-3.5.2]# python --version
    Python 3.5.2
    
    #查看安裝路徑(能夠省略這步)
    [root@web01 ~]# python
    Python 3.5.2 (default, May 27 2017, 18:39:42) 
    [GCC 4.4.7 20120313 (Red Hat 4.4.7-11)] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import sys
    >>> print(sys.path)
    ['', '/usr/local/python3/lib/python35.zip', '/usr/local/python3/lib/python3.5', '/usr/local/python3/lib/python3.5/plat-linux', '/usr/local/python3/lib/python3.5/lib-dynload', '/usr/local/python3/lib/python3.5/site-packages']
    >>> exit()
    安裝python3
  5. 安裝Django
    方式一:用pip3安裝
    
    pip3 install django
    
    升級方法:
    
    pip3 install django --upgrade
    安裝Django包
  6. 安裝PyMysql (選裝,具體看項目使用的數據庫)
    pip3 install PyMySQL
    
    #檢查模塊是否安裝成功
    [root@web01 ~]# python
    Python 3.5.2 (default, May 27 2017, 18:39:42) 
    [GCC 4.4.7 20120313 (Red Hat 4.4.7-11)] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import pymysql 
    >>> 
    >>> exit()
    安裝pyMysql模塊

c、uWSGI的安裝

# 安裝 uwsgi
[root@localhost teacher]# pip3 install uwsgi
安裝uwsgi模塊
[root@web01 nulige]# cd /home/nulige

[root@web01 nulige]# mkdir -p uwsgi_test

[root@web01 nulige]# cd uwsgi_test/

#測試文件

[root@web01 uwsgi_test]# vi test.py 

def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return [b"Hello World"] # python3
    #return ["Hello World"] # python2

# 啓動
[root@web01 uwsgi_test]# uwsgi --http :8000 --wsgi-file test.py

# 查看進程
[root@web01 ~]# ps -ef|grep uwsgi
root      17970   1000  0 19:12 pts/0    00:00:00 uwsgi --http :8000 --wsgi-file test.py
root      17972  17970  0 19:12 pts/0    00:00:00 uwsgi --http :8000 --wsgi-file test.py
root      17996  17973  0 19:14 pts/1    00:00:00 grep uwsgi

# 瀏覽器訪問
uWSGI的測試

 

d、nginx的安裝

  1.  更改操做系統默認的yum源
#以CentOS6.x 系統爲例

1、備份
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup

2、更換成國內源
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo

3、以後運行yum makecache生成緩存

  2. 安裝nginx

yum -y install nginx

 

6、啓動項目

 a、uWSGI的啓動

  1.   命令行啓動
    [root@python-dev ~]# uwsgi --http 192.168.14.4:8080 --file teacher/wsgi.py --static-map=/static=static

     

  2. 配置文件啓動
    # uwsig使用配置文件啓動
        [uwsgi]
        # 項目目錄
        chdir=/opt/project_teacher/teacher/
        # 指定項目的application
        module=teacher.wsgi:application
        # 指定sock的文件路徑
        socket=/opt/project_teacher/script/uwsgi.sock
        # 進程個數
        workers=5
        pidfile=/opt/project_teacher/script/uwsgi.pid
        # 指定IP端口
        http=192.168.31.123:8080
        # 指定靜態文件
        static-map=/static=/opt/test_project/teacher/static
        # 啓動uwsgi的用戶名和用戶組
        uid=root
        gid=root
        # 啓用主進程
        master=true
        # 自動移除unix Socket和pid文件當服務中止的時候
        vacuum=true
        # 序列化接受的內容,若是可能的話
        thunder-lock=true
        # 啓用線程
        enable-threads=true
        # 設置自中斷時間
        harakiri=30
        # 設置緩衝
        post-buffering=4096
        # 設置日誌目錄
        daemonize=/opt/project_teacher/script/uwsgi.log
    配置文件樣例
    # 經過配置文件啓動
            uwsgi --ini uwsgi.ini
            # 會生成兩個文件
                PID文件 他是標識這個程序所處的狀態
                SOCK文件  他是用來和其餘程序通訊的
        # 中止uwsgi
            uwsgi --stop uwsgi.pid
    
        # 重載配置
            uwsgi --reload uwsgi.ini
    配置文件啓動命令

     

b、nginx的配置

  

#先進入到配置文件:
vi /etc/nginx/conf.d/

# 這個server標識開始配置了
server {
        listen 80;  # 我要監聽那個端口
        server_name 10.129.205.183 ;  # 你訪問的路徑前面的url名稱
        access_log  /var/log/nginx/access.log  main;  # Nginx日誌配置
        charset  utf-8; # Nginx編碼
        gzip on;  # 啓用壓縮,這個的做用就是給用戶一個網頁,好比3M壓縮後1M這樣傳輸速度就會提升不少
        gzip_types text/plain application/x-javascript text/css text/javascript application/x-httpd-php application/json text/json image/jpeg image/gif image/png application/octet-stream;  # 支持壓縮的類型

        error_page  404           /404.html;  # 錯誤頁面
        error_page   500 502 503 504  /50x.html;  # 錯誤頁面

        # 指定項目路徑uwsgi
        location / {        # 這個location就和我們Django的url(r'^admin/', admin.site.urls),
            include uwsgi_params;  # 導入一個Nginx模塊他是用來和uWSGI進行通信的
            uwsgi_connect_timeout 30;  # 設置鏈接uWSGI超時時間
            uwsgi_pass unix:/opt/project_teacher/script/uwsgi.sock;  # 指定uwsgi的sock文件全部動態請求就會直接丟給他
        }

        # 指定靜態文件路徑
        location /static/ {
            alias  /opt/project_teacher/teacher/static/;
            index  index.html index.htm;
        }

    }
nginx的配置
/etc/init.d/nginx start
/etc/init.d/nginx stop

# 這裏有個命令configtest,Nginx配置是重啓生效的,若是你修改完了,不知道對不對又擔憂影響其餘人可使用它測試
/etc/init.d/nginx configtest

# 若是是生產環境的話Nginx正在運行,就不要直接stop start 或者 restart  直接reload就好了
# 對線上影響最低(生產環境用的方法)
/etc/init.d/nginx reload 
nginx命令

解決Django靜態配置文件丟失問題

問題緣由:
    是由於admin所需的js,css等靜態文件都在django的安裝目錄內,可是咱們並無配置指向Django的配置文件。

解決辦法:
    咱們能夠經過配置 STATIC_ROOT = os.path.join(BASE_DIR, "static_all")來指定靜態文件的默認家目錄是那裏,而後把項目裏全部的靜態文件都收集起來放到這個目錄下面。

收集命令:
    python3 manage.py collectstatic --noinput

修改Nginx 指定靜態路徑
    alias  /opt/test_project/teacher/static_all/;
靜態文件bug

參數優化,請參考官方文檔:

首先參考下官網的 things to know : http://uwsgi-docs.readthedocs.org/en/latest/ThingsToKnow.html

     我這邊最終啓動的命令以下: 

     uwsgi --socket 127.0.0.1:9090 -p 16 -l 8192 -M -R 100000  -z30 -L --wsgi-file  app.py --max-apps 65535 --stats 127.0.0.1:1717 --post-buffering 100M --cpu affinity --buffer-size 65535 --daemonize /tmp/uwsgi --pidfile /tmp/uwsgi.pid  --memory-report --threads 16

相關文章
相關標籤/搜索