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

1、如何在生產上部署Django?

Django的部署能夠有不少方式,採用nginx+uwsgi的方式是其中比較常見的一種方式。javascript

2、uwsgi介紹

uWSGI是一個Web服務器,它實現了WSGI協議、uwsgi、http等協議。Nginx中HttpUwsgiModule的做用是與uWSGI服務器進行交換。php

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

  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性能很是高html

uWSGI的主要特色以下java

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

If you are searching for a simple wsgi-only server, uWSGI is not for you, but if you are building a real (production-ready) app that need to be rock-solid, fast and easy to distribute/optimize for various load-average, you will pathetically and morbidly fall in love (we hope) with uWSGI.node

3、Django + Uwsgi + Nginx 生產部署

一、準備環境python

a、須要linux服務器一臺mysql

[root@web01 ~]# cat /etc/redhat-release 
CentOS release 6.6 (Final)
[root@web01 ~]# uname -r
2.6.32-504.el6.x86_64

b、在服務器上面安裝好Python和Djangolinux

一、安裝setuptoolsnginx

複製代碼
[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的時候會報錯,因此這裏提早處理啦!
複製代碼

二、安裝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
複製代碼

三、安裝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
複製代碼

四、安裝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()

複製代碼

5.安裝Django

複製代碼
方式一:用pip3安裝

pip3 install django

升級方法:

pip3 install django --upgrade
複製代碼
啓動django項目命令(備註:其它settings鏈接數據庫方法跟window同樣的)
#& 表示後臺啓動
python manage.py runserver 0.0.0.0:80 &   

六、安裝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()

複製代碼

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
複製代碼

啓動uwsgi

複製代碼
[root@web01 uwsgi_test]# uwsgi --http :8000 --wsgi-file test.py
*** Starting uWSGI 2.0.15 (64bit) on [Sat May 27 19:12:58 2017] ***
compiled with version: 4.4.7 20120313 (Red Hat 4.4.7-11) on 27 May 2017 18:48:50
os: Linux-2.6.32-504.el6.x86_64 #1 SMP Wed Oct 15 04:27:16 UTC 2014
nodename: web01
machine: x86_64
clock source: unix
pcre jit disabled
detected number of CPU cores: 1
current working directory: /home/nulige/uwsgi_test
detected binary path: /usr/local/python3/bin/uwsgi
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** 
*** WARNING: you are running uWSGI without its master process manager ***
your processes number limit is 14719
your memory page size is 4096 bytes
detected max file descriptor number: 1024
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
uWSGI http bound on :8000 fd 4
spawned uWSGI http 1 (pid: 17972)
uwsgi socket 0 bound to TCP address 127.0.0.1:38831 (port auto-assigned) fd 3
Python version: 3.5.2 (default, May 27 2017, 18:39:42)  [GCC 4.4.7 20120313 (Red Hat 4.4.7-11)]
*** Python threads support is disabled. You can enable it with --enable-threads ***
Python main interpreter initialized at 0x1ed4a90
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 72768 bytes (71 KB) for 1 cores
*** Operational MODE: single process ***
WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0x1ed4a90 pid: 17970 (default app)
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI worker 1 (and the only) (pid: 17970, cores: 1)
複製代碼

查看啓動端口

[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

在瀏覽器中,經過ip+端口號進行訪問

根據項目進行配置

複製代碼
# 啓動 uwsgi
    **進入項目目錄**
    **使用uwsgi啓動前確保無代碼問題致使經過runserver能夠正常啓動起來**
    uwsgi --http 192.168.31.123:8080 --file teacher/wsgi.py --static-map=/static=static #測試啓動

    # 解釋
        --http 這個就和runserver同樣指定IP 端口
        --file 這個文件就裏有一個反射,若是你在調用他的時候沒有指定Web Server就使用默認的
        -- static   作一個映射,指定靜態文件
複製代碼

二、生產環境配置

Nginx + uWSGI + Djangos配置方法:

複製代碼
# 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
複製代碼

# uwsig經常使用命令

複製代碼
    # 經過配置文件啓動
        uwsgi --ini uwsgi.ini
        # 會生成兩個文件
            PID文件 他是標識這個程序所處的狀態
            SOCK文件  他是用來和其餘程序通訊的
    # 中止uwsgi
        uwsgi --stop uwsgi.pid

    # 重載配置
        uwsgi --reload uwsgi.ini
複製代碼

d、nginx

#先換成國內yum源

複製代碼
#以CentOS6.x 系統爲例

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

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

三、以後運行yum makecache生成緩存
複製代碼

# 安裝nginx

yum -y install nginx

# 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經過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 
複製代碼

e、Django Admin靜態文件配置

有一個小bug: 

# 解決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/;
複製代碼

 

#參數優化

     首先參考下官網的 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

相關文章
相關標籤/搜索