• 使用FastCGI部署Django应用
    • FastCGI 简介
    • 运行你的 FastCGI 服务器
      • 停止FastCGI的行程
    • 在Apache中以FastCGI的方式使用Django
      • 指定 FastCGI Server 的位置
      • 使用mod_rewrite为FastCGI指定URL
    • FastCGI 和 lighttpd
      • 在一个lighttpd进程中运行多个Django站点
    • 在使用Apache的共享主机服务商处运行Django
      • 重启新产生的进程服务器

    使用FastCGI部署Django应用

    尽管将使用Apache和mod_python搭建Django环境是最具鲁棒性的,但在很多虚拟主机平台上,往往只能使用FastCGI

    此外,在很多情况下,FastCGI能够提供比mod_python更为优越的安全性和效能。 针对小型站点,相对于Apache来说FastCGI更为轻量级。

    FastCGI 简介

    如何能够由一个外部的应用程序很有效解释WEB 服务器上的动态页面请求呢? 答案就是使用FastCGI! 它的工作步骤简单的描述起来是这样的:

    和mod_python一样,FastCGI也是驻留在内存里为客户请求返回动态信息,而且也免掉了像传统的CGI一样启动进程时候的时间花销。 但于mod_python不同之处是它并不是作为模块运行在web服务器同一进程内的,而是有自己的独立进程。

    为什么要在一个独立的进程中运行代码?

    在以传统的方式的几种以mod_*方式嵌入到Apache的脚本语言中(常见的例如: PHP,Python/mod_python和Perl/mod_perl),他们都是以apache扩展模块的方式将自身嵌入到Apache进程中的。

    每一个Apache进程都是一个Apache引擎的副本,它完全包括了所有Apache所具有的一切功能特性(哪怕是对Django毫无好处的东西也一并加载进来)。 而FastCGI就不一样了,它仅仅把Python和Django等必备的东东弄到内存中。

    依据FastCGI自身的特点可以看到,FastCGI进程可以与Web服务器的进程分别运行在不同的用户权限下。 对于一个多人共用的系统来说,这个特性对于安全性是非常有好处的,因为你可以安全的于别人分享和重用代码了。

    如果你希望你的Django以FastCGI的方式运行,那么你还必须安装 flup 这个Python库,这个库就是用于处理FastCGI的。 很多用户都抱怨 flup 的发布版太久了,老是不更新。 其实不是的,他们一直在努力的工作着,这是没有放出来而已。

    运行你的 FastCGI 服务器

    FastCGI是以客户机/服务器方式运行的,并且在很多情况下,你得自己去启动FastCGI的服务进程。 Web服务器(例如Apache,lighttpd等等)仅仅在有动态页面访问请求的时候才会去与你的Django-FastCGI进程交互。 因为Fast-CGI已经一直驻留在内存里面了的,所以它响应起来也是很快的。

    记录

    在虚拟主机上使用的话,你可能会被强制的使用Web server-managed FastCGI进程。 在这样的情况下,请参阅下面的“在Apache共享主机里运行Django”这一小节。

    web服务器有两种方式于FastCGI进程交互: 使用Unix domain socket(在win32里面是 命名管道 )或者使用TCP socket.具体使用哪一个,那就根据你的偏好而定了,但是TCP socket弄不好的话往往会发生一些权限上的问题。 What you choose is a manner of preference; a TCP socket is usually easier due to permissions issues.

    开始你的服务器项目,首先进入你的项目目录下(你的 manage.py 文件所在之处),然后使用 manage.py runfcgi 命令:

    1. ./manage.py runfcgi [options]

    想了解如何使用 runfcgi ,输入 manage.py runfcgi help 命令。

    你可以指定 socket 或者同时指定 hostport 。当你要创建Web服务器时,你只需要将服务器指向当你在启动FastCGI服务器时确定的socket或者host/port。

    范例:

    在TCP端口上运行一个线程服务器:
    1. ./manage.py runfcgi method=threaded host=127.0.0.1 port=3033
    在Unix socket上运行prefork服务器:
    1. ./manage.py runfcgi method=prefork socket=/home/user/mysite.sock pidfile=django.pid
    启动,但不作为后台进程(在调试时比较方便):
    1. ./manage.py runfcgi daemonize=false socket=/tmp/mysite.sock

    停止FastCGI的行程

    如果你的FastCGI是在前台运行的,那么只需按Ctrl+C就可以很方便的停止这个进程了。 但如果是在后台运行的话,你就要使用Unix的 kill 命令来杀掉它。 然而,当你正在处理后台进程时,你会需要将其付诸于Unix kill的命令

    如果你在 manage.py runfcgi 中指定了 pidfile 这个选项,那么你可以这样来杀死这个FastCGI后台进程:

    1. kill `cat $PIDFILE`

    $PIDFILE 就是你在 pidfile 指定的那个。

    你可以使用下面这个脚本方便地重启Unix里的FastCGI守护进程:

    1. #!/bin/bash
    2. # Replace these three settings.
    3. PROJDIR="/home/user/myproject"
    4. PIDFILE="$PROJDIR/mysite.pid"
    5. SOCKET="$PROJDIR/mysite.sock"
    6. cd $PROJDIR
    7. if [ -f $PIDFILE ]; then
    8. kill `cat -- $PIDFILE`
    9. rm -f -- $PIDFILE
    10. fi
    11. exec /usr/bin/env - PYTHONPATH="../python:.." ./manage.py runfcgi socket=$SOCKET pidfile=$PIDFILE

    在Apache中以FastCGI的方式使用Django

    在Apache和FastCGI上使用Django,你需要安装和配置Apache,并且安装mod_fastcgi。 请参见Apache和mod_fastcgi文档: http://www.djangoproject.com/r/mod_fastcgi/ 。

    当完成了安装,通过 httpd.conf (Apache的配置文件)来让Apache和Django FastCGI互相通信。 你需要做两件事:

    • 使用 FastCGIExternalServer 指明FastCGI的位置。

    • 使用 mod_rewrite 为FastCGI指定合适的URL。

    指定 FastCGI Server 的位置

    FastCGIExternalServer 告诉Apache如何找到FastCGI服务器。 按照FastCGIExternalServer 文档( http://www.djangoproject.com/r/mod_fastcgi/FastCGIExternalServer/ ),你可以指明 socket 或者 host 。以下是两个例子:

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

    在这两个例子中, /home/user/public_html/ 目录必须存在,而 /home/user/public_html/mysite.fcgi 文件不一定存在。 它仅仅是一个Web服务器内部使用的接口,这个URL决定了对于哪些URL的请求会被FastCGI处理(下一部分详细讨论)。 (下一章将会有更多有关于此的介绍)

    使用mod_rewrite为FastCGI指定URL

    第二步是告诉Apache为符合一定模式的URL使用FastCGI。 为了实现这一点,请使用mod_rewrite 模块,并将这些URL重定向到 mysite.fcgi (或者正如在前文中描述的那样,使用任何在 FastCGIExternalServer 指定的内容)。

    在这个例子里面,我们告诉Apache使用FastCGI来处理那些在文件系统上不提供文件(译者注:

    1. <VirtualHost 12.34.56.78>
    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.*)$ /$1 [QSA,L]
    7. RewriteCond %{REQUEST_FILENAME} !-f
    8. RewriteRule ^/(.*)$ /mysite.fcgi/$1 [QSA,L]
    9. </VirtualHost>

    FastCGI 和 lighttpd

    lighttpd (http://www.djangoproject.com/r/lighttpd/) 是一个轻量级的Web服务器,通常被用来提供静态页面的访问。 它天生支持FastCGI,因此除非你的站点需要一些Apache特有的特性,否则,lighttpd对于静态和动态页面来说都是理想的选择。

    确保 mod_fastcgi 在模块列表中,它需要出现在 mod_rewritemod_access ,但是要在 mod_accesslog 之前。

    将下面的内容添加到你的lighttpd的配置文件中:

    1. server.document-root = "/home/user/public_html"
    2. 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. url.rewrite-once = (
    17. "^(/media.*)$" => "$1",
    18. "^/favicon\.ico$" => "/media/favicon.ico",
    19. "^(/.*)$" => "/mysite.fcgi$1",
    20. )

    在一个lighttpd进程中运行多个Django站点

    lighttpd允许你使用条件配置来为每个站点分别提供设置。 为了支持FastCGI的多站点,只需要在FastCGI的配置文件中,为每个站点分别建立条件配置项:

    1. # If the hostname is 'www.example1.com'...
    2. $HTTP["host"] == "www.example1.com" {
    3. server.document-root = "/foo/site1"
    4. fastcgi.server = (
    5. ...
    6. )
    7. ...
    8. }
    9. # If the hostname is 'www.example2.com'...
    10. $HTTP["host"] == "www.example2.com" {
    11. server.document-root = "/foo/site2"
    12. fastcgi.server = (
    13. ...
    14. )
    15. ...
    16. }

    你也可以通过 fastcgi.server 中指定多个入口,在同一个站点上实现多个Django安装。 请为每一个安装指定一个FastCGI主机。

    在使用Apache的共享主机服务商处运行Django

    许多共享主机的服务提供商不允许运行你自己的服务进程,也不允许修改 httpd.conf 文件。 尽管如此,仍然有可能通过Web服务器产生的子进程来运行Django。

    记录

    如果你要使用服务器的子进程,你没有必要自己去启动FastCGI服务器。 Apache会自动产生一些子进程,产生的数量按照需求和配置会有所不同。

    在你的Web根目录下,将下面的内容增加到 .htaccess 文件中:

    1. AddHandler fastcgi-script .fcgi
    2. RewriteEngine On
    3. RewriteCond %{REQUEST_FILENAME} !-f
    4. RewriteRule ^(.*)$ mysite.fcgi/$1 [QSA,L]

    接着,创建一个脚本,告知Apache如何运行你的FastCGI程序。 创建一个 mysite.fcgi 文件,并把它放在你的Web目录中,打开可执行权限。

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

    重启新产生的进程服务器

    如果你改变了站点上任何的python代码,你需要告知FastCGI。 但是,这不需要重启Apache,而只需要重新上传 mysite.fcgi 或者编辑改文件,使得修改时间发生了变化,它会自动帮你重启Django应用。 你可以重新上传mysite.fcgi或者编辑这个文件以改变该文件的时间戳。 当阿帕奇服务器发现文档被更新了,它将会为你重启你的Django应用。

    如果你拥有Unix系统命令行的可执行权限,只需要简单地使用 touch 命令:

    1. touch mysite.fcgi