通译www.djangobook.com之第二十一章:调度Django

来源:互联网 发布:淘宝女童装店铺最火 编辑:程序博客网 时间:2024/05/22 04:44

 The Django Book:第21章 支配Django

贯串此书我们谈到了一些促进Django开发的目标,便于运用,对程序员生手亲善,抽象反复的任务--这些都促进了Django的
开发人员
尽管这样,因为它起初是一个内部的,闭流的项目,一直有除此以外一个非常重要的目标:Django应当简单调度,而且应当使得用
有限的资源服务宏大的流量可行
这个目标的动机在你查看Django的背景时就很显然了:在堪萨斯的一份小小的的,家庭保有的报纸很难担子一流的服务器硬件,
之所以Django最初的开发人员关怀从有限的资源抽出绝佳的性能,确确实实,Django的开发人员作为他们自各儿系统的管理员几年时
间了--没急需专诚治理的足够的硬件--即或他们的站点一天处置千儿八百万的点击
Django成为开源项目后,因为不同的缘故至于性能的关切和使开发变轻便就变得非常重要:有癖好的开发者,念施用Django的
个人关于他们找出月月只要开销$十即可筹建小到中型流量的站点感到非常高兴
但是能够对付小的性能只是顺利的一半,Django也亟需拔高性能来满足贵族司和企业,这边Django采取了通常在LAMP相仿的
web堆栈的哲学,它正常号称"不分享任何东西"
LAMP?
首字母缩写LAMP最初用于描述一些用以驱动好多网站的时兴的开源软件:
Linux(操作系统)
Apache(web服务器)
MySQL(数据库)
PHP(编程语言)
但是其余时分这个首字母缩写更多的示意这些部类的开源软件堆栈的哲学而不是非一般的堆栈,之所以应Django运用Python而且
数据库不可知时,经过LAMP堆栈证实的该哲学渗漏了Django的调度心思
有点(多数很滑稽)至于创建相仿的首字母缩写来描述Django的技术堆栈的尝试,你的撰稿人们喜爱PAID(PostgreSQL,Apache
Internet和Django)也许LAPD(Linux,Apache,PostgreSQL和Django)

"不分享任何东西"
作为它的核心,"不分享任何东西"的哲学只是对整个软件堆栈松耦合的施用,这个架设唤起了对现阶段什么是主流架设的直接
响应:包装语言的独自的web应用服务器,数据库,web服务器--甚或一部分操作系统--到一个独自的处置(比如Java)
当到了急需伸缩性的每每,这可能是个重要的问题,几乎不能在多个不同的物理机器上分隔独自的处理工作,之所以独自的程
序亟需有力的服务器,当然,这些服务器价值上万甚或几十万美金,这让高性能的网站与缺少现款的个人和小公司无缘
尽管这样,LAMP社区注意到如其你把web堆栈的每个一部分分解成独自的组件,你可以轻巧的以便宜的服务器开始,而且跟着你
渐渐生长来简略的增添更便宜的服务器,如其你的$三,000的数据库服务器不能处置负荷,你简略的购置第二个(也许第三个,
可能第四个)直到它可以,如若你亟需更多储存能力,你可以平添一台NFS服务器
但是,为了让它工作,web程序务必终止假想同一服务器将处置每个请求--或许甚或一个独自请求的每个一部分,在高伸缩性的
LAMP(以及Django)调度中,多达一打车服务器或许与一个独自的页面相关!这点的反响是泛滥的,但是本质上为这几点:
一,状态不能在本土储存,换言之,在多个请求间可得到的任何数据务必储存在某类别型的持久化储存中,悉数据库或集中
缓存
二,软件不能假定资源是本土的,比如,web平台不能假想数据库运作于同一服务器,它务须能够联接远路数据库服务器
三,堆栈的每部分务必很简略腾挪或许复制:如若Apache鉴于某种原因不能为给定的支配工作,你应当可以以最小的忙胡搅
用除此以外的服务器轮换它
也许,在硬件级别:如其web服务器出故障了,你应当可以以最小的停产期用此外一个物理匣子轮换它,记住,整个哲学基于
在便宜的必需品硬件上支配,故障是预期的
你或者想到,Django或多或少透明的处置这个--Django没哪一部分违拗了这些准则--但是理解该哲学至于到了追求伸缩性时
会有相助
但是它工作吗?
该哲学或者至于在纸上(或许在你的银屏上)看上去良好,但是它真的工作吗?
好了,让我们见见一个不完整的一些基于该架设进行它们的业务的公司的列表,你或许认得一些名字:
Amazon
BLogger
Craigslist
Facebook
Google
LiveJournal
Slashdot
Wikipedia
Yahoo
YouTube
为了从应Harry赶超Sally...解释闻名的场景:"我们将拥有他们有的货色!"

个人嗜好的注意
在我们进去细节预先,一个高速的周边
开源因为所谓的"宗教战事"而闻名:好多(数目字的)墨汁洒在对于文本编辑器(emacs vs. vi),操作系统(Linux vs. Windows v
s. MacOS),数据库发动机(MySQL vs. PostgreSQL),以及--当然--编程语言的争议上
我们尝试远离这些战事,我们没足够的时间
尽管这样,当到了支配Django时有一些抉择,而且我们常常谋求我们的偏爱,既是述说这些偏好接近于这些战事中煽惑一个
保留条款同样风险,我们一般都避免了,但是鉴于完整性的缘故,我们将在这里述说它们,我们取舍:
Linux--明确的为Ubuntu--作为我们的操作系统
Apache和mod_python作为web服务器
PostgreSQL作为数据库服务器
当然,我们可以指出好多作出其余取舍并工作的良好的Django用户

怎的同Apache和mod_python应用Django
Apache和mod_python当前是在产品服务器上应用Django的最强健的装设
mod_python是在Apache中嵌入Python的Apache插件,它当服务器运行时载入Python代码到内存储器中,代码在一个Apache处置的
周期一直驻留在内存储器中,这带到比其余服务器安置更好的性能
Django亟需Apache二.x和mod_python三.x,而且你应当运用Apache的prefork MPM,而不是worker MPM
注意
配备Apache超出了此书的内容,之所以我们将简略的谈到急需的细节,幸运的是,如若你急需学习更多对于Apache的常识,有
大量的资源可以失去,内中我们喜爱的一些为:
免费的在线apache文档
Peter Wainwrite(Apress)的Pro Apache
Ben Laurie和Peter Laurie(O'Reilly)的Apache:The Definitive Guide

根本配备
为了用mod_python配备Django,第一确认你装配了Apache并激活了mod_python模块,这一般寓意在你的Apache配备里有1
个LoadModule指示,这正常看上去像这么:

Java代码
一.LoadModule python_module /usr/lib/apache二/modules/mod_python.so
LoadModule python_module /usr/lib/apache二/modules/mod_python.so

其后编者你的Apache配备并平添下边的货色:

Java代码
1.
2. SetHandler python-program
3. PythonHandler django.core.handlers.modpython
4. SetEnv DJANGO_SETTINGS_MODULE mysite.settings
5. PythonDebug On
6.

SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
PythonDebug On


确以为你的站点运用适合的DJANGO_SETTINGS_MODULE来轮换mysite.settings
这告诉Apache:"透过应用Django的mod_python handler来为任何在'/'停的URL施用mod_python",它传送DJANGO_SETTINGS_M
ODULE的值来让mod_python晓得运用哪个settings
注意我们施用Location指示,而不是Directory指示,后者用以指出你的文件系统的位置,而Location指出一个网站的URL结
构的位置,Directory在这里将没有意义
并且如若你手动改动了你的PYTHONPATH来置放你的Django项目,你将亟需告诉mod_python:
PythonPath "['/path/to/project'] + sys.path"
你也可认为了性能而增添比如PythonAutoReload Off等指示,参照mod_python documentation
来失去完整的选项列表
注意你应该在产品服务器中设立PythonDebug Off,如若你护持PythonDebug On,应mod_python出现问题时你的用户将看到丑恶
陋的(而且直露的)Python堆栈信息
重启Apache,Django将服务你的站点(也许你将该指示放在VirtualHost块里则时虚拟主机)的任何请求
注意
如其你在一个头目录调度Django--即,比"/"更深的地方--Django不会批改你的URL形式的URL前缀,这么,如若你的Apache
这么配备:

Java代码
1.
2. SetHandler python-program
3. PythonHandler django.core.handlers.modpython
4. SetEnv DJANGO_SETTINGS_MODULE mysite.settings
5. PythonDebug On
6.

SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
PythonDebug On


则你全部的URL形式将急需以"/mysite/"开始,鉴于这个缘故我们正常提议在你的域名可能虚拟主机的根支配Django

在同一Apache范例的多个Django装配
可以在同一Apache范例运作多个Django装配,只需像这么运用VirtualHost:

Java代码
一.NameVirtualHost *
2.
3.
4. ServerName www.example.com
5. # ...
6. SetEnv DJANGO_SETTINGS_MODULE mysite.settings
7.
8.
9.
10. ServerName www二.example.com
11. # ...
12. SetEnv DJANGO_SETTINGS_MODULE mysite.other_settings
13.
NameVirtualHost *


ServerName www.example.com
# ...
SetEnv DJANGO_SETTINGS_MODULE mysite.settings



ServerName www二.example.com
# ...
SetEnv DJANGO_SETTINGS_MODULE mysite.other_settings


如若你急需在同一VirtualHost安放两个Django装配,你将急需采取一个非一般的防护来军令状mod_python的代码缓存不会把事儿
弄糟,施用PythonInterpreter指示来给不同的Location指示诀别的interpreters:

Java代码
1.
2. ServerName www.example.com
3. # ...
4.
5. SetEnv DJANGO_SETTINGS_MODULE mysite.settings
6. PythonInterpreter mysite
7.
8.
9.
10. SetEnv DJANGO_SETTINGS_MODULE mysite.other_settings
11. PythonInterpreter mysite_other
12.
13.

ServerName www.example.com
# ...

SetEnv DJANGO_SETTINGS_MODULE mysite.settings
PythonInterpreter mysite



SetEnv DJANGO_SETTINGS_MODULE mysite.other_settings
PythonInterpreter mysite_other



只要它们在不同的两个Location块中,PythonInterpreter的值没有关系

施用mod_python运作开发服务器
因为mod_python缓存了载入的Python代码,当在mod_python调度Django站点时你将急需在历次你改动你的代码时重启Apache
这或者唤起争辩,之所以这里是避免它的高速技艺:
只需增添MaxRequestsPerChild 一到你的配置文件来逼迫Apache对每个请求从新载入每个货色,但是不用在产品服务器上做
这件事,不然我们将废止你的Django特权
如若你是施用疏散的print话语来调试的程序员,注意print话语在mod_python中没成效,它们不会期待中的在Apache日记
中出现,如若你急需在mod_python设立中打印调试信息,你将也许念应用Python的基准日记包可能增添调试信息到你的页面
的模板中

从同一Apache范例服务Django和media资料
Django自身要强务media资料,它把这项工作留给你取舍的Web服务器,我们提议运用独自的Web服务器--即,不是运作Django
的那个--来服务media,参照下部的伸缩性一部分
但是,如其你没其余抉择而不得不在Django的同一Apache VirtualHost上服务media资料,这里是为站点的非一般一部分封闭mod_
python:

Java代码
1.
2. SetHandler None
3.

SetHandler None


改动Location为你的media资料的根URL
你也可以施用LocationMatch来婚配正则表达式,比如,这在站点的根来建立Django但是展示的在media子目录和任如何.jpg,
.gif或.png煞尾的URL禁止Django:

Java代码
1.
2. SetHandler python-program
3. PythonHandler django.core.handlers.modpython
4. SetEnv DJANGO_SETTINGS_MODULE mysite.settings
5.
6.
7.
8. SetHandler None
9.
10.
11.
12. SetHandler None
13.

SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite.settings



SetHandler None



SetHandler None



错误处理
当你施用Apache/mod_python时,错处将被Django擒获--换言之,它们不会传播到Apache级别而且不会在Apache的error_lo
g中出现
例外是当你的Django设立中有点货色真个的弄糟时,这种情况下,你将在你的浏览器受看到一个"内部服务器差错"页面并在
你的Apache的error_log资料里看到完整的堆栈信息,error_log堆栈信息散布在多行(是的,这很丑陋而且很难翻阅,但这是
mod_python做事情的形式)

如若你失去瓜分故障
有时,当你装配Django时Apache疏失,应这发生时,差点儿一直是与Django自身不相关的两个缘故中的一个:
一,可能是你的Python代码在import pyexpat模块(用以解析XML),这或者与嵌入Apache的版本矛盾
参阅Expat以致Apache垮掉失去完整的信息
二,可能是由于你在同一Apache范例中运作mod_python和mod_php,并运用MySQL作为数据库后端
有点情况下,这招致因为PHP和Python的MySQL后端的版本矛盾发生的已知的mod_python问题
在mod_python FAQ条目有完整的信息
如其你对设立mod_python依然有问题,一个好事儿是让一个空的没Django构架的mod_python站点工作,这是分开mod_pytho
n专有的问题的简易的形式
让mod_python工作详细引见了这点
下一步应该是编者你的测试代码并平添你施用的Django专有的代码的import--你的视图,模型,URL配备,RSS配备之类,把
这些imports放在你的测试handler步骤里并在浏览器里访问你的测试URL,如若这招致失败,你就能确认是因为import Djan
go代码以致的问题,逐步减小imports的数量直到它终止失误,这么就找出了罗致问题的非一般的模块,如果有必要则深入到
模块中并观测它们的imports

怎的同FastCGI施用Django
诚然在Apache和mod_python停的Django是最强健的调度设立,许多人施用的是FastCGI是独一的选项的共享主机
并且,在某些情况下,FastCGI容许比mod_python更好的保险和或者更佳的性能,至于小站点,FastCGI也比Apache更轻量

什么是FastCGI?
FastCGI是让外部程序对Web服务器服务页面的有效的模式,Web服务器委任进入的Web请求(透过socket)给FastCGI,FastCGI
则施行代码并传送对答给Web服务器,Web服务器则顺次将对答回来给客户端Web浏览器
像mod_python同样,FastCGI容许代码驻留在内存储器中,这就容许0起步时间来服务请求,不像mod_python,FastCGI历程不在
Web服务器历程里运作,而是一个独自的,持久的历程
为何在独自的历程里运作代码?
Apache里守旧的mod_*配备把不同的脚本语言(特别是PHP,Python和Perl)嵌入在你的Web服务器过程空间里边,固然这减小了
起动时间--由于代码不需要为每个请求读硬盘--它是之内存应用为代价的
每个Apache历程失去Apache发动机的拷贝,包括Django不施用的Apache的全部特征,在另一方面,FastCGI历程只拥有Python和
Django的内存储器过渡
因为FastCGI的天性,也可以以一个不同的用户帐号运作的历程而不是Web服务器历程,这在共享系统里是一个良好的保险好
处,由于这寓意你可以从其余用户保护你的代码

必要条件:flup
在你开始同Django应用FastCGI先期,你将亟需装配flup,这是用于处置FastCGI的Python库,有点用户汇报了老版本flup的
页面推迟,之所以你或许念施用最新的SVN版本

运作你的FastCGI服务器
FastCGI基于客户端-服务器模型操作,在多数情况下你将起动你自各儿的FastCGI服务器过程,应服务器急需载入动态页面时
你的Web服务器(Apache,lighttpd,可能其余的)只联系你的Django-FastCGI过程,因为后盾历程已经将代码运作在内存储器中,
则可以高速的服务对答
注意
如若你在一个共享主机系统上,你或许将被强逼应用Web服务器治理的FastCGI历程,参照下部的运用Web服务器治理的过程来
运作Django来失去更多信息
Web服务器可以用两种模式联接FastCGI服务器:它可以施用Unix域socket(在Win32系统上的"定名管道")可能应用TCP socket
你的抉择是一种偏好,因为权限问题TCP socket更容易
为了起步你的服务器,第一进来你的项目的索引(你的manage.py所在的地方),其后施用runfcgi选项运作manage.py:

Java代码
1../manage.py runfcgi [options]
./manage.py runfcgi [options]

如其你指定help作为runfcgi后头独一的选项,它将展示全部可得到的选项的列表
你将亟需指定socket或许host和port,其后,当你起步你的Web服务器时,你将只需在起动FastCGI服务器时在你指定的host/
port也许socket指出它
一些事例应当可以相助解释这点
一,在一个TCP端口运作一个threaded服务器:

Java代码
1../manage.py runfcgi method=threaded host=127.0.0.1 port=3033
./manage.py runfcgi method=threaded host=127.0.0.1 port=3033

二,在一个Unix域socket运作一个preforked服务器:

Java代码
1../manage.py runfcgi method=prefork socket=/home/user/mysite
./manage.py runfcgi method=prefork socket=/home/user/mysite

三,不要后台老板化(背景化)历程来运作(利于调试):

Java代码
1../manage.py runfcgi daemonize=false socket=/tmp/mysite.sock
./manage.py runfcgi daemonize=false socket=/tmp/mysite.sock


终止FastCGI后台老板过程
如其你有一个历程运作在前台,很简略终止它:容易的输入Ctrl-C将终止和退出FastCGI服务器,但是当你处置靠山过程时,
你将亟需求诸于Unix kill下令
如其你指定pidfile选项到你的manage.py runfcgi,你可以像这么杀掉运作的FastCGI靠山过程:

Java代码
一.kill `cat $PIDFILE`
kill `cat $PIDFILE`

这边$PIDFILE为你指定的pidfile
为了使在Unix上重启你的FastCGI后盾历程很简单,你可以施用这个小shell脚本:

Java代码
1.#!/bin/bash
2.
3.# Replace these three settings.
四.PROJDIR="/home/user/myproject"
五.PIDFILE="$PROJDIR/mysite.pid"
六.SOCKET="$PROJDIR/mysite.sock"
7.
八.cd $PROJDIR
九.if [ -f $PIDFILE ]; then
10. kill `cat -- $PIDFILE`
11. rm -f -- $PIDFILE
12.fi
13.
14.exec /usr/bin/env - /
15. PYTHONPATH="../python:.." /
16. ./manage.py runfcgi socket=$SOCKET pidfile=$PIDFILE
#!/bin/bash

# Replace these three settings.
PROJDIR="/home/user/myproject"
PIDFILE="$PROJDIR/mysite.pid"
SOCKET="$PROJDIR/mysite.sock"

cd $PROJDIR
if [ -f $PIDFILE ]; then
kill `cat -- $PIDFILE`
rm -f -- $PIDFILE
fi

exec /usr/bin/env - /
PYTHONPATH="../python:.." /
./manage.py runfcgi socket=$SOCKET pidfile=$PIDFILE


Apache和FastCGI
为了同Apache和FastCGI施用Django,你将急需装配和配备Apache,并让mod_fastcgi装配和激活,参照Apache和mod_fastcgi
文档来失去指示
万一你建立了这些货色,透过编者httpd.conf(Apache配备)资料来将Apache指向你的Django FastCGI范例
你将急需做两件事儿:
一,应用FastCGIExternalServer指示来指定你的FastCGI服务器的位置
二,施用mod_rewrite来将URLs指向适宜的FastCGI

指定FastCGI服务器的位置
FastCGIExternalServer指示告诉Apache怎么找出你的FastCGI服务器
FastCGIExternalServer文档解释到,
你可以指定socket或许host,这里是两者的例证:

Java代码
1.# Connect to FastCGI via a socket / named pipe.
二.FastCGIExternalServer /home/user/public_html/mysite.fcgi -socket /home/user/mysite.sock
3.
4.# Connect to FastCGI via a TCP host/port.
五.FastCGIExternalServer /home/user/public_html/mysite.fcgi -host 127.0.0.1:3033
# Connect to FastCGI via a socket / named pipe.
FastCGIExternalServer /home/user/public_html/mysite.fcgi -socket /home/user/mysite.sock

# Connect to FastCGI via a TCP host/port.
FastCGIExternalServer /home/user/public_html/mysite.fcgi -host 127.0.0.1:3033

甭管哪种景况,/home/user/public_html/mysite.fcgi实质上不需要存在,它只是Web服务器内部应用的URL--一个示意关于
一个URL的哪个请求应当透过FastCGI处置的钩子(下部分对此讲授更多)

运用mod_rewrite将URLs指向FastCGI
第二步是告诉Apache对婚配某一形式的URLs应用FastCGI,为了干这个,应用mod_rewrite模块并重写URLs到mysite.fcgi(或
者你在FastCGIExternalServer指示里指定的任何东西,上头的一部分解释了)
在这个例证中,我们告诉Apache应用FastCGI来处置不示意文件系统中的资料和不以/media/造端的任何请求,如若你在应用
Django的admin站点,这可能是最常见的景况:

Java代码
1.
2. ServerName example.com
3. DocumentRoot /home/user/public_html
4. Alias /media /home/user/python/django/contrib/admin/media
5. RewriteEngine On
6. RewriteRule ^/(media.*)$ /$一 [QSA,L]
7. RewriteCond %{REQUEST_FILENAME} !-f
8. RewriteRule ^/(.*)$ /mysite.fcgi/$一 [QSA,L]
9.

ServerName example.com
DocumentRoot /home/user/public_html
Alias /media /home/user/python/django/contrib/admin/media
RewriteEngine On
RewriteRule ^/(media.*)$ /$一 [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^/(.*)$ /mysite.fcgi/$一 [QSA,L]



FastCGI和lighttpd
lighttpd是一个轻量的Web服务器,它一般用来服务静态资料,它
生就支持FastCGI,这么,如其你的站点没Apache专有的需求的话,它是服务静态和动态页面的好的抉择
确认mod_fastcgi在你的模块列表中,座落mod_rewrite和mod_access以后,但不再mod_accesslog以后,你也许将也想要mod_
alias来服务admin的media
平添下列内容到你的lightpd配置文件:

Java代码
一.server.document-root = "/home/user/public_html"
二.fastcgi.server = (
3. "/mysite.fcgi" => (
4. "main" => (
5. # Use host / port instead of socket for TCP fastcgi
6. # "host" => "127.0.0.1",
7. # "port" => 3033,
8. "socket" => "/home/user/mysite.sock",
9. "check-local" => "disable",
10. )
11. ),
12.)
13.alias.url = (
14. "/media/" => "/home/user/django/contrib/admin/media/",
15.)
16.
17.url.rewrite-once = (
18. "^(/media.*)$" => "$一",
19. "^/favicon/.ico$" => "/media/favicon.ico",
20. "^(/.*)$" => "/mysite.fcgi$一",
21.)
server.document-root = "/home/user/public_html"
fastcgi.server = (
"/mysite.fcgi" => (
"main" => (
# Use host / port instead of socket for TCP fastcgi
# "host" => "127.0.0.1",
# "port" => 3033,
"socket" => "/home/user/mysite.sock",
"check-local" => "disable",
)
),
)
alias.url = (
"/media/" => "/home/user/django/contrib/admin/media/",
)

url.rewrite-once = (
"^(/media.*)$" => "$一",
"^/favicon/.ico$" => "/media/favicon.ico",
"^(/.*)$" => "/mysite.fcgi$一",
)


在一个lighttpd范例上运作多个Django站点
lighttpd让你应用"有条件的配备"来容许对每个主机自定义配备,为了指定多个FastCGI站点,只需为每个站点增添有条件的
块来包围你的FastCGI配备:

Java代码
1.# If the hostname is 'www.example一.com'...
2.$HTTP["host"] == "www.example一.com" {
3. server.document-root = "/foo/site一"
4. fastcgi.server = (
5. ...
6. )
7. ...
8.}
9.
10.# If the hostname is 'www.example二.com'...
11.$HTTP["host"] == "www.example二.com" {
12. server.document-root = "/foo/site二"
13. fastcgi.server = (
14. ...
15. )
16. ...
17.}
# If the hostname is 'www.example一.com'...
$HTTP["host"] == "www.example一.com" {
server.document-root = "/foo/site一"
fastcgi.server = (
...
)
...
}

# If the hostname is 'www.example二.com'...
$HTTP["host"] == "www.example二.com" {
server.document-root = "/foo/site二"
fastcgi.server = (
...
)
...
}

你也可以经过在fastcgi.server指示里指定多个条目来在同一站点上运作多个Django装配,为每项增添一个FastCGI主机

在共享主机服务商上同Apache运作Django
好多共享主机服务商不允许你运作你自个儿的服务器后盾过程后者编者httpd.conf资料,这种情况下,依然可以施用Web服务器
生成的过程运作Django
注意
如其你应用这一部分解释的Web服务器生成的过程,你没必要自各儿起动FastCGI服务器,Apache将作为伸缩性急需而自个儿生成1
些过程
在你的Web源目录,增添下列内容到一个叫.htaccess的资料:

Java代码
一.AddHandler fastcgi-script .fcgi
二.RewriteEngine On
三.RewriteCond %{REQUEST_FILENAME} !-f
四.RewriteRule ^(.*)$ mysite.fcgi/$一 [QSA,L]
AddHandler fastcgi-script .fcgi
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ mysite.fcgi/$一 [QSA,L]

其后,创造一个告诉Apache怎的生成你的FastCGI程序的金莲本,创设一个mysite.fcgi并把它放在你的Web索引并保准它可
施行:

Java代码
1.#!/usr/bin/python
二.import sys, os
3.
4.# Add a custom Python path.
五.sys.path.insert(零, "/home/user/python")
6.
7.# Switch to the directory of your project. (Optional.)
8.# os.chdir("/home/user/myproject")
9.
10.# Set the DJANGO_SETTINGS_MODULE environment variable.
11.os.environ['DJANGO_SETTINGS_MODULE'] = "myproject.settings"
12.
13.from django.core.servers.fastcgi import runfastcgi
14.runfastcgi(method="threaded", daemonize="false")
#!/usr/bin/python
import sys, os

# Add a custom Python path.
sys.path.insert(零, "/home/user/python")

# Switch to the directory of your project. (Optional.)
# os.chdir("/home/user/myproject")

# Set the DJANGO_SETTINGS_MODULE environment variable.
os.environ['DJANGO_SETTINGS_MODULE'] = "myproject.settings"

from django.core.servers.fastcgi import runfastcgi
runfastcgi(method="threaded", daemonize="false")


重启生成的服务器
如其你在你的站点改动了任何Python代码,你将急需告诉FastCGI代码已经更动,但是这种情况下没有必要重启Apache,而是
只需从新上传mysite.fcgi--或许编者该资料--这么该资料的时间戳将改变,应Apache发现该资料已经更新,它将为你重启你
的Django程序
如若你在Unix系统上可以访问命令行shell,你可以透过施用touch下令容易的达到这点:

Java代码
一.touch mysite.fcgi
touch mysite.fcgi


增高伸缩性
既是你懂得了怎么让Django运作在一个独自的服务器上,让我们见见你怎的拔高一个Django装配的伸缩性,这一部分将通览1
个站点怎么从一个独自的服务器到可以服务每小时几百万点击率的高伸缩性的集群
但是,注意差一点每个特大型站点以不同的模式大很主要,之所以增高伸缩性不是一个分寸量天下的操作,下头的内容应当满足显
示正常的准则,我们将尝试指出我们可以在哪儿作出不同的取舍
第一,我们将做一个十分大的假想并额外谈一下在Apache和mod_python停拔高伸缩性,虽然我们好多顺利的中到特大型FastCGI部
署,我们简略的更相熟Apache

独自的服务器
半数以上站点以运作在一个独自的服务器上开始,运用看上去像这么的架设:

这对小到中等的站点工作的良好,而且非常便宜--你可以开销少于$三,000设计来将Django安放在一个独自的服务器
尽管这样,应流量增多后你将很快进来对不同的软件开展资源争夺的化境,数据库服务器和web服务器喜爱将整个服务器归属
它们自个儿来应用,之所以当在同一服务器上运行时它们常常为独有同一资源(RAM,CPU)而"斗殴"
这可以经过将数据库服务器腾挪到第二台机器上来轻便解决

把数据库服务器分开开
分开数据库服务器
对Django而谈,这十分简略:你将简略的急需改动DATABASE_HOST设立为你的数据库服务器的IP或DNS,如若可以的话运用IP可
会是个好主意,依赖于DNS来联接你的web和数据库服务器可能是个大问题
透过将数据库服务器分开,我们的架设现下看上去像这么:

这边我们开始进来一般所谓的N层架设,不用被专业术语吓倒,它只是指web堆栈分开到不同的物理机器的不同的层
这么的话如其你期待急需增多超过一个独自的数据库服务器,现时就开始思考联接池和/或数据库复制可能是个好主意,此书
几乎没有足够的空间来议论这些议题--不幸的是--之所以你将急需参照你的数据库文档和/或社区来失去更多的信息

独自的media服务器
关于独自的服务器设立我们依然剩有一个大问题:从处置动态内容的同一匣子服务media
这两个活动在不同的环境客店理最好,把它们糅杂在一个匣子里你将不会把任何一个处置得良好,之所以下一步是把media隔绝
开来--即,不是Django视图生成的任何东西--到一个专诚的服务器:
[img]http://media.djangobook.com/content/chapter21/scaling-三.png[img]
志向情况下,这个media服务器应当运作一个独自的优化来公布静态media的web服务器
lighttpd和tux在这里都是良好的抉择,但是一个重量级的独自Apache也可以工作
关于静态内容很多的站点--相片,视频之类--搬动到一个独自的media服务器愈加主要,而且或者应该是拔高伸缩性的第一步
但是这一步或者略微有的狡猾,Django的admin亟需能够写上传media到media服务器(MEDIA_ROOT设立统制了这些media应当写
到哪里)如若media坐落除此以外一个服务器,你将急需安顿一种对这个写跨网络发作的模式
作这个的最简略的形式是施用NFS来设立media服务器的media索引到web服务器,如其你设立它们到MEDIA_ROOT指定的同一位
放,media 上传将Just Work™

载荷均衡和冗余
在这点上我们现下尽量多的分解事儿,这个3服务器的设立应当处置十分大的流量--我们从这种架设服务了每日千儿八百万的
点击率--之所以如若你增长的更多,你将亟需开始增添冗余
实际上这是好事:初看一眼上边的图像展示了即令三个服务器中的独自的一个垮掉了,你将毁掉你的整个站点,之所以当你平添
额外的服务器时,你不单增加了容量,你也增加了可靠性
为了这个事例,让我们假想web服务器第一打击容量,很简单失去运作在不同的硬件上的Django站点的多个拷贝--只需复制所
有的代码到多个机器上,其后在它们上边起步Apache
尽管这样,你将急需除此而外一个软件来在你的多个服务器上散发流量:一个负荷均衡器,你可以购置昂贵和私有的硬件负荷均衡
器,但是有一些十分高质量的开源载荷均衡器软件在那里
Apache的mod_proxy便是一个选项,但是我们发现Perlbal更牛X
它是写memcached(参照第14章)的一些家伙写的一个负荷均衡器和倒转署理
注意
如若你施用FastCGI,你可以透过分开你的前台web服务器和后端FastCGI历程到不同的机器来达到一样的散发/载荷均衡,前
台的服务器本质上变为载荷均衡器,后端的FastCGI过程则轮换了Apache/mod_python/Django服务器
web服务器现下集群以后,我们进化的架设开始看上去更复杂了:

注企图像中web服务器被当做"集群"来指出服务器的数量是根本可变的,万一你在前面有一个负荷均衡器,你可以轻便的平添
和剔除后端web服务器而没一丁点的停产期

变大
在这点上,接下来的几步是最后一步的衍生:
一,当你急需更多的数据库性能时,你将急需平添复制数据库服务器,MySQL包孕了内建的复制,PostgreSQL用户应当查询
Slony和pgpool来诀别失去复制和联接池
二,如若独自的载荷均衡器不够,你可以在前面平添更多的负荷均衡器并施用round-robin DNS散发它们
三,如若独自的media服务器不能满足,你可以平添更多的media服务器并用你的载荷均衡集群散发载荷
四,如其你亟需更多的缓存,你可以增添专诚的缓存服务器
五,在任何一步,如其集群不能处置的良好你可以平添更多的服务器到集群
在这些迭代以后,一个高伸缩性的架设或许看上去像这么:

虽然我们只在每个级别展示了两到三个服务器,大抵对你可以增添的服务器的数量没限制

性能调优
如其你有大量的银两,对性能问题你可以只是砸硬件,但是对其他人,性能调优是务必的
注意
趁便说一下子,如其谁有大量的白银而又在翻阅此书,请思忖对Django项目的真实的捐赠,我们也接受未雕琢的钻石和金锭
不幸的是,性能调优更多的是一门艺术而不是一门科学,它甚或比增高伸缩性更难写,如若你对支配高伸缩性的Django程序
很热衷,你应当花销大量的时间学习怎的整合你的堆栈的每个一部分
但是,这里是一些我们从前几年议论的Django专有的调优小技能:

没太多的RAM
就算真个昂贵的RAM每千兆字节只价值$200--盆尼与花消在调优的时间上比照,购置尽量多的你能担子的伏的RAM,其后
再买多一点
更快的微处理器不会真的改善性能太多,大多数web服务器花销90%的时间在硬盘IO上,万一你开始互换,性能将亡故,更快的
硬盘或者略微有些相助,但是它们比无足轻重的RAM昂贵好多
如其你有多个服务器,置放你的RAM的第一个地方乃是数据库服务器,如其你可以担子的讫,失去足够多的RAM来让你的整个
数据库放到内存储器中,这应当不难,LJWorld.com的数据库--包括回顾至一九八九年的50万稿子--少于二GB
下一步是对你的web服务器最大化RAM,志向的景况是永不互换,如其抵达这点你应当可以承负绝大多数普普通通的流量

封锁Keep-Alive
Keep-alive是HTTP的一个特征,它容许多个HTTP请求对一个独自的TCP联接服务,避免了TCP建立/销毁的过渡
第一眼看样子这不错,但是实质上它可以杀掉一个Django站点的性能,如若你刚好从一个独自的服务器服务media,每个浏览你
的站点的用户将实质上最好情况下每十秒从Django服务器失去一个页面,这让HTTP服务器等候下一个keep-alive请求,而1
个闲工夫的HTTP服务器只是耗费一个激活的服务器应当施用的RAM

运用memcached
虽然Django支持好多不同的缓存后端,它们中没一个相近memcached同样快,如其你有一个高流量的站点,不用与此同时应用
其余缓存后端,直接应用memcached

常常运用memecached
当然,如若你实际上不施用memcached的话抉择它将不会给你带到好处,这边第14章是你最好的友人:学习怎么应用Django的
缓存构架,并且在任何也许的地方施用它,主动的,尽先的缓存通常是护持站点在高流量停的独一的思忖

加入叙谈
Django堆栈的每个一部分--从Linux到Apache到PostgreSQL也许MySQL--后边都有一个卓越的社区,如若你真个想从你的服务器
失去最后的一%,参与你的软件后头的开源社区并谋求相助,绝大多数免费软件社区成员将乐意相助
最后也确认加入Django社区,你的低微的著者们只是一个十分活泼的,生长中的Django开发人员群组中的两个成员,我们的
社区提供一个数量硕大的群体心得

祝你好运!
我们祝你运作的Django站点有最好的命运运限,不管它是你和你友人的一个小玩具仍是下一个谷歌
本文来源:
我的异常网
Java Exception

原创粉丝点击