Nginx 和 Gunicorn 部署 Django項目

Nginx 和 Gunicorn 部署 Django項目

前提準備:python

  • linux服務器 + python3.6.2
  • 上傳項目代碼至服務器

Django 項目中會有一些 CSS、JavaScript 等靜態文件,爲了可以方便地讓 Nginx 處理這些靜態文件的請求,咱們把項目中的所有靜態文件收集到一個統一的目錄下,這個目錄一般位於 Django 項目的根目錄,而且命名爲 static。爲了完成這些任務,須要在項目的配置文件裏作一些必要的配置:linux

settings.py:
STATIC_URL = '/static/'
# 加入下面的配置
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

STATIC_ROOT 指明瞭靜態文件的收集目錄,即項目根目錄(BASE_DIR)下的 static 文件夾。
若是說咱們的項目是先後端分離的狀況,這時候靜態文件的目錄確定是不同的,這時候可讓python自動幫咱們收集一些靜態文件,而後幫咱們放到指定的目錄裏面去,nginx

  • 修改settings.py文件
STATIC_ROOT='/var/www/static/'
STATIC_URL='/static/'
  • 收集全部靜態文件到static_root指定目錄:git

    python3 manage.py collectstatic

配置Nginx

新建一個基於不一樣端口的虛擬主機github

[root@192.168.32.130 /usr/local/webserver/nginx/conf/vhosts]$ cat gunicorn_django.conf     
upstream mydjangoproject {
        server unix:/data/app/Library_Management_System/script/gunicorn.sock;
    }

server {

        listen       10000;
        server_name  192.168.32.130;
        location / {
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_redirect off;
            if (!-f $request_filename) {
                proxy_pass http://mydjangoproject;
                break;
            }
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
        location /static/ {
            alias /var/www/static/;
        }
    }

django項目的站點添加容許訪問的主機:web

ALLOWED_HOSTS = ['*']算法

配置好以後檢查一下並啓動django

[root@192.168.32.130 /usr/local/webserver/nginx/conf/vhosts]$ /usr/local/webserver/nginx/sbin/nginx  -t
nginx: the configuration file /usr/local/webserver/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/webserver/nginx/conf/nginx.conf test is successful
[root@192.168.32.130 /usr/local/webserver/nginx/conf/vhosts]$ /usr/local/webserver/nginx/sbin/nginx  -s reload

安裝配置Gunicorn

[root@192.168.32.130 ~]$ pip3 install gunicorn

經過命令行直接啓動

經過gunicorn啓動Django項目,在你的django project目錄下運行:後端

[root@192.168.32.130 /data/app/Library_Management_System]$ gunicorn Library_Management_System.wsgi:application --bind=unix:/data/app/Library_Management_System/script/gunicorn.sock
[2019-12-01 05:56:47 -0800] [119248] [INFO] Starting gunicorn 20.0.4
[2019-12-01 05:56:47 -0800] [119248] [INFO] Listening at: unix:/data/app/Library_Management_System/script/gunicorn.sock (119248)
[2019-12-01 05:56:47 -0800] [119248] [INFO] Using worker: sync
[2019-12-01 05:56:47 -0800] [119251] [INFO] Booting worker with pid: 119251

啓動完成以後,會夯住在這裏,說明已經啓動了,只要沒有報錯,訪問你的網頁,就可以正常訪問了

夯住了怎辦呢、可使用nohub命令來後臺運行。具體不寫了,本身百度去。

Gunicorn 與 uwsgi 的區別,用哪一個好呢

[線上環境部署Django,nginx+uwsgi 和nginx+gunicorn,這兩種方案,應該如何選擇?]

Gunicorn

Gunicorn是使用Python實現的WSGI服務器, 直接提供了http服務, 而且在woker上提供了多種選擇, gevent, eventlet這些都支持, 在多worker最大化裏用CPU的同時, 還可使用協程來提供併發支撐, 對於網絡IO密集的服務比較有利.

同時Gunicorn也很容易就改形成一個TCP的服務, 好比doge重寫worker類, 在針對長鏈接的服務時, 最好開啓reuse_port, 避免worker進程負載不均。

一句話配置簡單

uWSGI

不一樣於Gunicorn, uWSGI是使用C寫的, 它的socket fd建立, worker進程的啓動都是使用C語言系統接口來實現的, 在worker進程處理循環中, 解析了http請求後, 使用python的C接口生成environ對象, 再把這個對象做爲參數塞到暴露出來的WSGI application函數中調用. 而這一切都是在C程序中進行, 只是在處理請求的時候交給python虛擬機調用application. 徹底使用C語言實現的好處是性能會好一些.

除了支持http協議, uWSGI還實現了uwsgi協議, 通常咱們會在uWSGI服務器前面使用Nginx做爲負載均衡, 若是使用http協議, 請求在轉發到uWSGI前已經在Nginx這裏解析了一遍, 轉發到uWSGI又會從新解析一遍. uWSGI爲了追求性能, 設計了uwsgi協議, 在Nginx解析完之後直接把解析好的結果經過uwsgi協議轉發到uWSGI服務器, uWSGI拿到請求按格式生成environ對象, 不須要重複解析請求. 若是用Nginx配合uWSGI, 最好使用uwsgi協議來轉發請求.

除了是一個WSGI服務器, uWSGI仍是一個開發框架, 它提供了緩存, 隊列, rpc等等功能, 在github找找就會發現有人用它的緩存寫了一個Django cache backend, 用它的隊列實現異步任務這些東西, 可是用了這些東西技術棧也就跟uWSGI綁定在一塊兒, 因此通常也只是把uWSGI看成WSGI服務器來用。

一句話配置複雜

Nginx

使用多個進程監聽同一端口就繞不開驚羣這個話題, fork子進程, 子進程共享listen socket fd, 多個子進程同時accept阻塞, 在請求到達時內核會喚醒全部accept的進程, 然而只有一個進程能accept成功, 其它進程accept失敗再次阻塞, 影響系統性能, 這就是驚羣. Linux 2.6內核更新之後多個進程accept只有一個進程會被喚醒, 可是若是使用epoll仍是會產生驚羣現象.

Nginx爲了解決epoll驚羣問題, 使用進程間互斥鎖, 只有拿到鎖的進程才能把listen fd加入到epoll中, 在accept完成後再釋放鎖.

可是在高併發狀況下, 獲取鎖的開銷也會影響性能, 通常會建議把鎖配置關掉. 直到Nginx 1.9.1更新支持了socket的SO_REUSEPORT選項, 驚羣問題纔算解決, listen socket fd再也不是在master進程中建立, 而是每一個worker進程建立一個經過SO_REUSEPORT 選項來複用端口, 內核會自行選擇一個fd來喚醒, 而且有負載均衡算法.

Gunicorn與uWSGI都支持reuse_port選項, 在使用時能夠經過壓測來評估一下reuse_port是否能提高性能.

通常咱們會在Gunicorn/uWSGI前面再加一層Nginx, 這樣作的緣由有一下幾點:

  1. 作負載均衡
  2. 靜態文件服務器
  3. 更安全
  4. 扛併發
相關文章
相關標籤/搜索