教育行業(yè)A股IPO第一股(股票代碼 003032)

全國咨詢/投訴熱線:400-618-4000

Django部署方案簡(jiǎn)介

更新時(shí)間:2016年09月13日17時(shí)35分 來源:傳智播客 瀏覽次數(shù):

引:Django是Python眾多web框架中提供功能最全最豐富的一個(gè),那么我們?cè)趯?shí)際應(yīng)用中通常怎么去部署Django呢?下面我們就來看一看Django的部署方案有哪些。

1. Python web 程序的部署方法:

Django是采用python寫的web框架,我們先來看下python的web程序的9種部署方法:

· mod_python,這是apache內(nèi)置的模塊,很嚴(yán)重的依賴于mod_python編譯使用的python版本,和apache配套使用,不推薦;

· cgi,這個(gè)太old,不推薦,而且nginx不支持cgi方式,只能用lighttpd或者apache;

· fastcgi ,這個(gè)是目前流行最廣的做法,通過flup模塊來支持的,在nginx里對(duì)應(yīng)的配置指令是 fastcgi_pass;

· spawn-fcgi,這個(gè)是fastcgi多進(jìn)程管理程序,lighttpd安裝包附帶的,和flup效果一樣,區(qū)別是flup是 python代碼級(jí)引入,spawn-fcgi是外部程序,spawn-fcgi用途很廣,可以支持任意語言開發(fā)的代碼,php、python、perl,只要你代碼實(shí)現(xiàn)了fastcgi接口,它都可以幫你管理你的進(jìn)程;

· scgi,全名是Simple Common Gateway Interface,也是cgi的替代版本,scgi協(xié)議很簡(jiǎn)單,和fastcgi差不多,只是沒有怎么推廣開來,nginx對(duì)應(yīng)的配置指令是scgi_pass,你想用就用,flup也支持;

· http,nginx使用proxy_pass轉(zhuǎn)發(fā),這個(gè)要求后端application必須內(nèi)置一個(gè)能處理高并發(fā)的http server,在python的web框架當(dāng)中,只能選擇tornado;

python程序員喜歡發(fā)明輪子,tornado除了是一個(gè)web framework之外,它還可以單獨(dú)提供高性能http server,所以,如果你采用其他python框架寫代碼,比如說bottle,也一樣可以通過import tornado 來啟動(dòng)一個(gè)高性能的http server,同樣的可以采用http協(xié)議和nginx一起來部署。擴(kuò)展開來,python包里面能處理高并發(fā)的http server還有很多,比如說gevent,也可以被其他框架引用來支持http方式部署。

· uwsgi,包括4部分組成:

o uwsgi協(xié)議

o web server內(nèi)置支持協(xié)議模塊

o application服務(wù)器協(xié)議支持模塊

o 進(jìn)程控制程序

nginx從0.8.4開始內(nèi)置支持uwsgi協(xié)議,uwsgi協(xié)議非常簡(jiǎn)單,一個(gè)4個(gè)字節(jié)header加一個(gè)body,body可以是很多協(xié)議的包,比如說http,cgi等(通過header里面字段標(biāo)示)。

uwsgi的特點(diǎn)在于自帶的進(jìn)程控制程序,它是用c語言編寫,使用natvie函數(shù),其實(shí)和spawn-fcgi/php-fpm類似。所以u(píng)wsgi可以支持多種應(yīng)用框架,包括(python、lua、ruby、erlang、go)等等

· Gunicorn,和uwsgi類似的工具,從rails的部署工具(Unicorn)移植過來的。但是它使用的協(xié)議是 WSGI,全稱是Python Web Server Gateway Interface ,這是python2.5時(shí)定義的官方標(biāo)準(zhǔn)(PEP 333 ),根紅苗正,而且部署比較簡(jiǎn)單;

· mod_wsgi,apache的一個(gè)module,也是支持WSGI協(xié)議,https://code.google.com/p/modwsgi/

2. Nginx + uWSGI + Django

先來澄清幾個(gè)概念:

WSGI: WSGI是一種Web服務(wù)器網(wǎng)關(guān)接口。它是一個(gè)Web服務(wù)器(如nginx)與應(yīng)用服務(wù)器(如uWSGI服務(wù)器)通信的一種規(guī)范。

uwsgi: uwsgi同WSGI一樣是一種通信協(xié)議,而uWSGI是實(shí)現(xiàn)了uwsgi和WSGI兩種協(xié)議的Web服務(wù)器。

uwsgi協(xié)議是一個(gè)uWSGI服務(wù)器自有的協(xié)議,它用于定義傳輸信息的類型(type of information),每一個(gè)uwsgi packet前4byte為傳輸信息類型描述,它與WSGI相比是兩樣?xùn)|西。

uWSGI: uWSGI是一個(gè)Web服務(wù)器,它實(shí)現(xiàn)了WSGI協(xié)議、uwsgi、http等協(xié)議。 Nginx中HttpUwsgiModule的作用是與uWSGI服務(wù)器進(jìn)行交換。

uWSGI的主要特點(diǎn)如下:

超快的性能

低內(nèi)存占用(實(shí)測(cè)為apache2的mod_wsgi的一半左右)

多app管理

詳盡的日志功能(可以用來分析app性能和瓶頸)

高度可定制(內(nèi)存大小限制,服務(wù)一定次數(shù)后重啟等)

由于uWSGI有著上述優(yōu)點(diǎn),通常采用Nginx + uWSGI + Django來部署,性能與穩(wěn)定性都不錯(cuò)。

部署方法:

1 安裝uwsgi

pip install uwsgi

2 寫配置文件 yourfile.ini (文件名可自定義)

[uwsgi]

socket = 127.0.0.1:3031

chdir = /home/foobar/myproject/

wsgi-file = myproject/wsgi.py

processes = 4

threads = 2

master= True

pidfile = yourfile.pid

daemonize = yourfile.log

3 執(zhí)行 uwsgi yourfile.ini

4 nginx 配置

location / {

uwsgi_pass 127.0.0.1:8630;

include uwsgi_params;

}

3. Nginx + Tornado + Django

Tornado是一個(gè)異步web框架和服務(wù)器,所以在開發(fā)長輪詢的chat之類應(yīng)用非常的合適,但是其實(shí)本身也是一個(gè)高性能的http服務(wù)器,也可以作為一個(gè)WSGIServer。所以即使網(wǎng)站沒有使用Tornado的框架,而是用了web.py或者是Django來開發(fā), Tornado依然可以用來加速網(wǎng)站。使用Tornado來代替fastCGI可以大幅提高性能,且可以承載的并發(fā)能力也有了成倍的提高。

部署方法:

采用Nginx通過upstream來反向代理到N個(gè)Tornado的服務(wù)器實(shí)例上的部署方式。

Setp1:安裝supervisord

由于Tornado并沒有自身提供Daemon的能力,所以需要用一個(gè)服務(wù)管理工具來管理Tornado的進(jìn)程,supervisord是用Python實(shí)現(xiàn)的一款非常實(shí)用的進(jìn)程管理工具??梢院芊奖愕墓芾鞱過進(jìn)程,且支持進(jìn)程分組。Supervisord可以通過sudo easy_install supervisor安裝,當(dāng)然也可以通過Supervisord官網(wǎng)下載后setup.py install安裝。

Step2: 給Django的站點(diǎn)增加一個(gè)Tornado的服務(wù)器文件(比如serv.py)

創(chuàng)建一個(gè)文件Serv.py在Django站點(diǎn)的根目錄(Django 1.4中應(yīng)該放到和urls.py同一級(jí)目錄),內(nèi)容如下:

import os

import sys

from tornado.options import options, define, parse_command_line

import django.core.handlers.wsgi

import tornado.httpserver

import tornado.ioloop

import tornado.web

import tornado.wsgi

HERE = os.path.dirname(os.path.abspath(file_))

sys.path.append(_HERE)

sys.path.append(os.path.join(_HERE, '..'))

sys.path.append(os.path.join(_HERE, '../contrib'))

os.environ['DJANGO_SETTINGS_MODULE'] = "settings"

def main(port):

wsgi_app = tornado.wsgi.WSGIContainer(

django.core.handlers.wsgi.WSGIHandler())

tornado_app = tornado.web.Application(

[('.*', tornado.web.FallbackHandler, dict(fallback=wsgi_app)),

])

server = tornado.httpserver.HTTPServer(tornado_app)

server.listen(port)

tornado.ioloop.IOLoop.instance().start()

if __name__ == 'main':

main(int(sys.argv[1]))

我這里通過第一個(gè)參數(shù)來指定Tornado服務(wù)監(jiān)聽的端口。這樣比較靈活,這點(diǎn)我們?cè)诤竺娴牟襟E會(huì)用到。這個(gè)時(shí)候我們可以通過python Serv.py 8000這個(gè)命令來啟動(dòng)服務(wù)器

Step3: 配置Supervisord

第一步安裝的Supervisord還沒有配置,所以我們需要先創(chuàng)建一個(gè)配置文件的樣板。在root權(quán)限下執(zhí)行echo_supervisord_conf > /etc/supervisord.conf這個(gè)時(shí)候在/etc/創(chuàng)建了配置文件,用vim打開這個(gè)文件,在配置文件的屁股后面加上以下這一段

[program:web]

command=python /var/www/site/Serv.py 80%(process_num)02d

process_name=%(program_name)s_%(process_num)02d

umask=022

startsecs=0

stopwaitsecs=0

redirect_stderr=true

stdout_logfile=/tmp/codoon.log

numprocs=4

numprocs_start=1

這個(gè)配置會(huì)啟動(dòng)4個(gè)Tornado的服務(wù)進(jìn)程分別監(jiān)聽 8001,8002,8003,8004 這四個(gè)端口

command這一行是要執(zhí)行的命令,這里是用 python /var/www/site/Serv.py 端口號(hào)來啟動(dòng)Tornado的服務(wù)進(jìn)程 80%(process_num)02d 的用途是通過進(jìn)程編號(hào)來生成端口號(hào)。下面的process_name這個(gè)參數(shù)也會(huì)用到。這里要指定的文件名就是上一步我們創(chuàng)建那個(gè)Serv.py文件

process_name是進(jìn)程的名字,由于這里要啟動(dòng)4個(gè)進(jìn)程,所以要用process_num來區(qū)分

umask是程序執(zhí)行的權(quán)限參數(shù)

startsecs這個(gè)參數(shù)是程序啟動(dòng)的等待時(shí)間

stopwaitsecs這個(gè)參數(shù)是程序停止的等待時(shí)間

redirect_stderr這個(gè)參數(shù)將錯(cuò)誤流重定向到std的流輸出,這樣可以省去一個(gè)日志文件的配置,當(dāng)然也可以不用這個(gè)參數(shù)分開配置日志文件

stdout_logfile 這個(gè)參數(shù)是STD流輸出日志文件的路徑,Tornado會(huì)輸出所有的請(qǐng)求和錯(cuò)誤信息,通過這個(gè)可以統(tǒng)一做日志處理,分隔什么的,在程序里就只需要print到std流就行了。

numprocs 這個(gè)參數(shù)指定了進(jìn)程的數(shù)量,這里是4,表明要啟動(dòng)4個(gè)Tornado進(jìn)程

numprocs_start 這個(gè)參數(shù)指定了進(jìn)程號(hào)的起始編號(hào),這里是1,這樣前面的command和process_name里的%(process_num)02d部分就會(huì)在執(zhí)行的時(shí)候被替換為01~05的字符串

配置修改完成后:wq保存退出,執(zhí)行:

supervisorctl reload

重新加載配置后,這些進(jìn)程就啟動(dòng)起來了

Step4:修改配置Nginx

首先找到在vhost目錄里你的站點(diǎn)配置文件,打開后,在頭上增加upstream的內(nèi)容

upstream frontends {

server 127.0.0.1:8001;

server 127.0.0.1:8002;

server 127.0.0.1:8003;

server 127.0.0.1:8004;

}

然后在Server配置節(jié)里找到

location / { 這個(gè)配置節(jié)

以前是用的FastCGI,所以里面的配置可能是這樣子的

host and port to fastcgi server

fastcgi_pass 127.0.0.1:8081;

fastcgi_param PATH_INFO $fastcgi_script_name;

fastcgi_param REQUEST_METHOD $request_method;

fastcgi_param QUERY_STRING $query_string;

fastcgi_param CONTENT_TYPE $content_type;

fastcgi_param CONTENT_LENGTH $content_length;

fastcgi_pass_header Authorization;

fastcgi_param REMOTE_ADDR $remote_addr;

fastcgi_param SERVER_PROTOCOL $server_protocol;

fastcgi_param SERVER_PORT $server_port;

fastcgi_param SERVER_NAME $server_name;

fastcgi_intercept_errors off;

把這些統(tǒng)統(tǒng)刪掉,變成了這樣

location / {

}

在{}中加入upstream的配置,變成如下樣子

location / {

proxy_pass_header Server;

proxy_set_header Host $http_host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Scheme $scheme;

proxy_pass http://frontends;

proxy_next_upstream error;

}

保存配置文件后執(zhí)行 讓nginx重啟的指令 nginx -s reload(注意 nginx文件在不同發(fā)行版中位置有差別)

0 分享到:
和我們?cè)诰€交談!