1. 程式人生 > >Django + Uwsgi + Nginx 實現生產環境部署

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

max python 安裝 pla flask框架 for static form 環境

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

Django的部署可以有很多方式,采用nginx+uwsgi的方式是其中比較常見的一種方式。

二、uwsgi介紹

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

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

  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性能非常高

技術分享

uWSGI的主要特點如下

  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.

三、Django + Uwsgi + Nginx 生產部署

1、準備環境

a、需要linux服務器一臺

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

這裏安裝方法省略。。。。(不懂可以百度解決)

c、uwsgi

# 安裝 uwsgi
[[email protected] teacher]# pip3 install uwsgi

測試uwsgi

[[email protected] nulige]# cd /home/nulige

[[email protected] nulige]# mkdir -p uwsgi_test

[[email protected] nulige]# cd uwsgi_test/

#測試文件
[[email protected] 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

[[email protected] 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)

查看啟動端口

[[email protected] ~]# 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
    **進入項目目錄**
    **使用uwsgi啟動前確保無代碼問題導致通過runserver可以正常啟動起來**
    uwsgi --http 192.168.31.123:8080 --file teacher/wsgi.py --static-map=/static=static #測試啟動

    # 解釋
        --http 這個就和runserver一樣指定IP 端口
        --file 這個文件就裏有一個反射,如果你在調用他的時候沒有指定Web Server就使用默認的
        -- static   做一個映射,指定靜態文件

2、生產環境配置

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 系統為例

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生成緩存

# 安裝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/;

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