nginx+uWSGI+django+virtualenv+supervisor發佈web服務器

 

nginx+uWSGI+django+virtualenv+supervisor發佈web服務器

 

導論

WSGI是Web服務器網關接口。它是一個規範,描述了Web服務器如何與Web應用程序通訊,以及Web應用程序如何連接在一塊兒以處理一個請求,(接收請求,處理請求,響應請求)
基於wsgi運行的框架有Bottle,Django,Flask,用於解析動態HTTP請求
支持WSGI的服務器
    wsgiref
        python自帶的web服務器
    Gunicorn
        用於linux的 python wsgi Http服務器,經常使用於各類django,flask結合部署服務器。
    mode_wsgi
        實現了Apache與wsgi應用程序的結合
    uWSGI
        C語言開發,快速,自我修復,開發人員友好的WSGI服務器,用於Python Web應用程序的專業部署和開發。

在部署python程序web應用程序時,能夠根據性能的需求,選擇合適的wsgi server,不一樣的wsgi server區別在於併發支持上,有單線程,多進程,多線程,協程的區別,其功能仍是近似,無非是請求路由,執行對應的函數,返回處理結果。




Django部署

Django的主要部署平臺是 WSGI,這是用於Web服務器和應用程序的Python標準。

Django的 startproject管理命令設置一個簡單的默認WSGI配置,能夠根據須要爲您的項目進行調整,並指示任何符合WSGI的應用程序服務器使用。

application 
使用WSGI部署的關鍵概念是應用程序服務器用於與代碼通訊的 application 可調用。它一般在服務器可訪問的Python模塊中做爲名爲 application 的對象提供。

startproject 命令建立包含這樣的 application 可調用的文件 <project_name>/wsgi.py. ,它被Django的開發服務器和生產WSGI部署使用。
WSGI服務器從其配置中獲取 application 可調用的路徑。 Django的內置服務器,即 runserver 命令,從 WSGI_APPLICATION 設置讀取它。
1 首先nginx 是對外的服務接口,外部瀏覽器經過url訪問nginx,

2  nginx接收到瀏覽器發送過來的http請求,將包進行解析,分析url,若是是靜態文件請求就直接訪問用戶給nginx配置的靜態文件目錄,直接返回用戶請求的靜態文件,若是不是靜態文件,而是一個動態的請求,那麼nginx就將請求轉發給uwsgi, uwsgi接收到請求以後將包進行處理,處理成wsgi能夠接受的格式,併發給wsgi, wsgi 根據請求調用應用程序的某個文件的某個函數,最後處理完將返回值再次交給uwsgi,uwsgi將返回值進行打包,打包成uwsgi可以接收的格式,uwsgi接收wsgi 發送的請求,並轉發給nginx, nginx最終將返回值返回給瀏覽器。

3 要知道第一級的nginx並非必須的,uwsgi徹底能夠完成整個的和瀏覽器交互的流程,可是要考慮到某些狀況

(1) 安全問題,程序不能直接被瀏覽器訪問到,而是經過nginx,nginx只開放某個接口,uwsgi自己是內網接口,這樣運維人員在nginx上加上安全
性的限制,能夠達到保護程序的做用。

(2)負載均衡問題,一個uwsgi極可能不夠用,即便開了多個work也是不行,畢竟一臺機器的cpu和內存都是有限的,有了nginx作代理,一個nginx可
以代理多臺uwsgi完成uwsgi的負載均衡。

(3)靜態文件問題,用django或是uwsgi這種東西來負責靜態文件的處理是很浪費的行爲,並且他們自己對文件的處理也不如nginx好,因此整個靜態文件的處理都直接由nginx完成,靜態文件的訪問徹底不去通過uwsgi以及其後面的東西。
爲何要用nginx和uwsgi
# uwsgi在運行django項目的時候,必須找到django的wsgi.py文件內容中的參數,否則會報no application...的錯
# 也就是得有這個實例化的對象才行: application = get_wsgi_application()

#解決辦法就是 uwsgi,必定要找到wsgi.py這個文件
wsgi.py文件的做用

 

nginx官網html

http://nginx.org/en/

nginx有關uwsgi模塊介紹python

http://nginx.org/en/docs/http/ngx_http_uwsgi_module.html

你們都學過了django,用django寫了各類功能linux

我們都知道django是一個web框架,方便咱們快速開發web程序,http請求的動態數據就是由web框架來提供處理的。nginx

前面咱們也對nginx簡單的介紹了,本文將nginx、WSGI、uwsgi、uWSGI、django這幾個關係梳理一下。程序員

wsgi    全稱web server gateway interface,wsgi不是服務器,也不是python模塊,只是一種協議,描述web server如何和web application通訊的規則。
運行在wsgi上的web框架有bottle,flask,django
uwsgi    和wsgi同樣是通訊協議,是uWSGI服務器的單獨協議,用於定義傳輸信息的類型
uWSGI    是一個web服務器,實現了WSGI協議,uwsgi協議。a
nginx    web服務器,更加安全,更好的處理處理靜態資源,緩存功能,負載均衡,所以nginx的強勁性能,配合uWSGI服務器會更加安全,性能有保障。
django 高級的python web框架,用於快速開發,解決web開發的大部分麻煩,程序員能夠更專一業務邏輯,無須從新造輪子

邏輯圖

web服務器web

傳統的c/s架構,請求的過程是
客戶端 > 服務器 
服務器 > 客戶端
服務器就是:1.接收請求 2.處理請求 3.返回響應

web框架層面試

HTTP的動態數據交給web框架,例如django遵循MTV模式處理請求。
HTTp協議使用url定位資源,urls.py將路由請求交給views視圖處理,而後返回一個結果,完成一次請求。
web框架使用者只須要處理業務的邏輯便可。

若是將一次通訊轉化爲「對話」的過程sql

Nginx:hello wsgi,我剛收到一個請求,你準備下而後讓django來處理吧apache

WSGI:好的nginx,我立刻設置環境變量,而後把請求交給djangodjango

Django:謝謝WSGI,我處理完請求立刻給你響應結果

WSGI:好的,我在等着

Django:搞定啦,麻煩wsgi吧響應結果傳遞給nginx

WSGI:太棒了,nginx,響應結果請收好,已經按照要求傳遞給你了

nginx:好滴。我把響應交給用戶。合做愉快

Django Nginx+uwsgi 安裝配置

在前面的章節中咱們使用 python manage.py runserver 來運行服務器。這隻適用測試環境中使用。

正式發佈的服務,須要一個能夠穩定而持續的服務器。

基礎開發環境配置

yum groupinstall "Development tools"
yum install zlib-devel bzip2-devel pcre-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel

提早安裝好python3環境

https://www.cnblogs.com/pyyu/p/7402145.html

virtualenv

請確保你的虛擬環境正常工做
https://www.cnblogs.com/pyyu/p/9015317.html

安裝django2.1.7

pip3 install django==2.1.7
#建立django項目mysite
django-admin startproject mysite
#建立app01
python3 manage.py startapp app01

mysite/settings.py

#settings.py設置
ALLOWED_HOSTS = ['*']
install app01

mysite/urls.py

from app01 import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('hello_django/', views.hello),
]

app01/views.py

from django.shortcuts import render, HttpResponse

# Create your views here.
def hello(request):
    print('request is :',request)
    return HttpResponse('django is ok ')

安裝uWSGI

# 進入虛擬環境venv,安裝uwsgi
(venv) [root@slave 192.168.11.64 /opt]$pip3 install uwsgi # 檢查uwsgi版本
(venv) [root@slave 192.168.11.64 /opt]$uwsgi --version
2.0.17.1
# 檢查uwsgi python版本
uwsgi --python-version

1. 運行簡單的uWSGI

# 建立一個testqishi.py, 寫入以下內容:

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

# 經過命令去啓動python web應用 
uwsgi --http :8000 --wsgi-file testqishi.py
        http :8000: 使用http協議,端口8000
        wsgi-file testqishi.py: 指定一個支持python wsgi協議的文件(django下是wsgi.py),這裏是testqishi.py

uWsgi熱加載python程序

項目已經部署上去了,可是後面常常會臨時修改代碼,每一次修改事後都須要手動重啓一下uwsgi, 特別麻煩,因此咱們要用到自動重啓python程序功能

注意: 這個uwsgi支持熱加載的問題,面試可能會問到

# 在啓動命令後面加上參數
uwsgi --http :8088 --module book_manage.wsgi --py-autoreload=1  # 此命令應該在django項目目錄下才能夠,--module才能找到它的參數book_manage.wsgi
    --py-autoreload=1  # 參數表示自動加載python配置
# 發佈命令
command= /home/venv/bin/uwsgi --uwsgi 0.0.0.0:8000 --chdir /opt/mysite --home=/home/venv --module mysite.wsgi
# 此時修改django代碼,uWSGI會自動加載django程序,頁面生效

運行django程序

#mysite/wsgi.py  確保找到這個文件
uwsgi --http :8000 --module mysite.wsgi
  • module mysite.wsgi: 加載指定的wsgi模塊

使用uwsgi配置文件去啓動項目

前面學的啓動uwsgi的命令都特別長,由於加了不少參數,太難記了,那怎麼辦? 咱們有更好的方法,就是在項目下面建立一個uwsgi.ini的文件,而後經過讀這個文件來啓動uwsgi

# uwsgi.ini配置文件, uwsgi支持ini、xml等多種配置方式,本文以 ini 爲例, 在/etc/目錄下新建uwsgi.ini,添加以下配置:

# uwsgi.ini file
[uwsgi]

# Django-related settings
# the base directory (full path)
chdir           = /opt/mysite
# Django's wsgi file
module          = mysite.wsgi
# the virtualenv (full path)
home            = /opt/venv
# process-related settings
# master
master          = true
# maximum number of worker processes
processes       = 1
# the socket (use the full path to be safe
socket          = 0.0.0.0:8000
# ... with appropriate permissions - may be needed
# chmod-socket    = 664
# clear environment on exit
vacuum          = true
# uwsgi.ini配置文件詳解

[uwsgi]
# Django-related settings
# the base directory (full path)
# 寫上項目的絕對路徑
chdir           = /opt/book_manage
# Django's wsgi file
# 填寫找到django的wsgi文件,填寫相對路徑,以chdir參數爲相對路徑
module          = book_manage.wsgi
# the virtualenv (full path)
# 填寫虛擬環境的絕對路徑
home            = /root/Envs/book_manage_env/
# process-related settings
# master
#啓動uwsgi主進程
master          = true
# maximum number of worker processes
processes       = 1
# the socket (use the full path to be safe
#若是你使用了nginx,作反向代理,必須填寫socket連接,而不是http參數
socket          = 0.0.0.0:8000
#若是你不用nginx,直接使用uwsgi,運行一個http服務端,就用這個http參數
http = 0.0.0.0:8000
# ... with appropriate permissions - may be needed
# chmod-socket    = 664
# clear environment on exit
vacuum          = true
uwsgi.ini配置詳解

指定配置文件啓動命令

uwsgi --ini  /etc/uwsgi_nginx.ini

使用ngixn處理django的靜態文件

因爲uwsgi對靜態文件的處理不好,然而nginx處理靜態文件是一把手,因此咱們的項目部署還須要結合nginx來使用

1 設置django的靜態文件目錄並收集, 咱們打開mysite/settings.py, 加入這一項配置:

STATIC_ROOT='/opt/static'
STATIC_URL = '/static/'
STATICFILES_DIRS=[
    os.path.join(BASE_DIR,"static"),
]

上述的參數STATIC_ROOT用在哪?

2 經過python3 manage.py collectstatic 收集全部你使用的靜態文件保存到STATIC_ROOT

python3 manage.py collectstatic

# STATIC_ROOT 文件夾 是用來將全部STATICFILES_DIRS中全部文件夾中的文件,以及各app中static中的文件都複製過來
# 把這些文件放到一塊兒是爲了用nginx等部署的時候更方便

3 查看django的靜態文件收集目錄

ls /opt/static

4 修改nginx.conf配置nginx反向代理,找到uwsgi項目,且配置nginx處理uwsgi的靜態文件

worker_processes  1;
error_log  logs/error.log;
pid        logs/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  logs/access.log  main;
    sendfile        on;
    keepalive_timeout  65;
  # nginx反向代理uwsgi
    server {
        listen       80;
        server_name  qishijd.com;
        location / {
            # nginx自帶ngx_http_uwsgi_module模塊,起到nginx和uwsgi交互做用
            # 經過uwsgi_pass設置服務器地址和協議,將動態請求轉發給uwsgi處理
            include  /opt/nginx112/conf/uwsgi_params;
            uwsgi_pass 0.0.0.0:8000;
            root   html;
            index  index.html index.htm;
        }
        # nginx處理靜態頁面資源
        # 當用戶請求是qishijd.com/static/的時候, 就會進入這個location匹配
        # 經過alias參數進行路徑別名,讓nginx去/opt/static底下去找靜態資源
     location /static {
            alias /opt/static; }
     # nginx處理媒體資源
     location /media{
            alias /opt/nginx112/media;  
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

配置完啓動nginx

supervisor

supervisor 是基於 python 的任務管理工具,用來自動運行各類後臺任務,固然你也能直接利用 nohup 命令使任務自動後臺運行,但若是要重啓任務,每次都本身手動 kill 掉任務進程,這樣很繁瑣,並且一旦程序錯誤致使進程退出的話,系統也沒法自動重載任務。

這裏咱們要配置基於virtualenv的supervisor

因爲supervisor在python3下沒法使用,所以只能用python2去下載!!!!!!

 

1 安裝supervisor

# 注意此時已經退出虛擬環境了!!!!!
easy_install supervisor

# 若是沒有easy_install的話,就yum安裝一個setuptools工具就能夠用了
yum install python-setuptools

2 經過命令生成supervisor的配置文件

echo_supervisord_conf > /etc/supervisord.conf

而後再/etc/supervisord.conf末尾添加上以下代碼!!!!!!

[program:book_manage]
command=/root/Envs/book_manage_env/bin/uwsgi /opt/book_manage/uwsgi.ini
stopasgroup=true
killasgroup=true
supervisord.conf配置文件參數解釋
[program:xx]是被管理的進程配置參數,xx是進程的名稱
[program:xx]
command=/opt/apache-tomcat-8.0.35/bin/catalina.sh run  ; 程序啓動命令
autostart=true       ; 在supervisord啓動的時候也自動啓動
startsecs=10         ; 啓動10秒後沒有異常退出,就表示進程正常啓動了,默認爲1秒
autorestart=true     ; 程序退出後自動重啓,可選值:[unexpected,true,false],默認爲unexpected,表示進程意外殺死後才重啓
startretries=3       ; 啓動失敗自動重試次數,默認是3
user=tomcat          ; 用哪一個用戶啓動進程,默認是root
priority=999         ; 進程啓動優先級,默認999,值小的優先啓動
redirect_stderr=true ; 把stderr重定向到stdout,默認false
stdout_logfile_maxbytes=20MB  ; stdout 日誌文件大小,默認50MB
stdout_logfile_backups = 20   ; stdout 日誌文件備份數,默認是10
; stdout 日誌文件,須要注意當指定目錄不存在時沒法正常啓動,因此須要手動建立目錄(supervisord 會自動建立日誌文件)
stdout_logfile=/opt/apache-tomcat-8.0.35/logs/catalina.out
stopasgroup=false     ;默認爲false,進程被殺死時,是否向這個進程組發送stop信號,包括子進程
killasgroup=false     ;默認爲false,向進程組發送kill信號,包括子進程
supervisord.conf配置文件參數解釋

 

[program:my]
#command=/opt/venv/bin/uwsgi --ini  /etc/uwsgi_nginx.ini  #這裏是結合virtualenv的命令 和supervisor的精髓!!!!
command= /home/venv/bin/uwsgi --uwsgi 0.0.0.0:8000 --chdir /opt/mysite --home=/home/venv --module mysite.wsgi
#--home指的是虛擬環境目錄 --module找到 mysite/wsgi.py

3 最後啓動supervisor,完成uWSGI啓動django,nginx反向代理

supervisord -c /etc/supervisord.conf # 啓動supervisor
supervisorctl -c /etxc/supervisord.conf restart book_manage  # 重啓book_manage項目
supervisorctl -c /etc/supervisord.conf [start|stop|restart] [program-name|all]
# 任務管理命令以下:有兩種,一個是參數形式, 一個是交互式
# 參數形式  
supervisorctl -c /etc/supervisor.conf stop/start/restart   all
supervisorctl -c /etc/supervisor.conf start crm_knight

# 交互式形式
supervisorctl -c /etc/supervisor.conf 

 從新加載supervisor

1、添加好配置文件後

2、更新新的配置到supervisord    

supervisorctl update
3、從新啓動配置中的全部程序

supervisorctl reload
4、啓動某個進程(program_name=你配置中寫的程序名稱)

supervisorctl start program_name
5、查看正在守候的進程

supervisorctl
6、中止某一進程 (program_name=你配置中寫的程序名稱)

pervisorctl stop program_name
7、重啓某一進程 (program_name=你配置中寫的程序名稱)

supervisorctl restart program_name
8、中止所有進程

supervisorctl stop all
注意:顯示用stop中止掉的進程,用reload或者update都不會自動重啓。

 

參考文檔:http://uwsgi-docs-zh.readthedocs.io/zh_CN/latest/tutorials/Django_and_nginx.html

 uwsgi熱加載:https://uwsgi-docs-zh.readthedocs.io/zh_CN/latest/Management.html

相關文章
相關標籤/搜索