[摘要] 如何用 FastCGI 运行 Django
摘要自 Django 文档:http://www.djangoproject.com/documentation/fastcgi/
------------------------------------------------------------------------------------
首先要安装 flup (http://www.saddi.com/software/flup/),
这是 Python 处理 FastCGI 的库。
FactCGI 采用 c/s 模型,独立的运行一个进程。在需要处理请求时,web 服务器(apache, httpd,..)直接和 FactCGI 进程进行通信即可。
web 服务器可通过两种办法和 FastCGI server 连接:
1. Unix domain socket(或 win32 的“命名管道")
2. TCP socket
通常 TCP socket 更简单,因为权限问题比较好配置。
如何启动 FactCGI 服务器:
到项目目录中,执行:
./manage.py runfcgi [options]
如果要看帮助:
./manage.py runfcgi help
在选项中,需要指定一个 socket 或 host 和 port 的组合,这样的话,当你启动 web server 时,就可以通过这些信息来连接到 FactCGI 服务器。
例子
在 TCP 端口中运行一个线程内服务器:
./manage.py runfcgi method=threaded host=127.0.0.1 port=3033
在 Unix domain socket 上运行一个 preforked 服务器:
./manage.py runfcgi method=prefork socket=/home/user/mysite.sock pidfile=django.pid
不作为后台进程执行(便于调试):
./manage.py runfcgi daemonize=false socket=/tmp/mysite.sock
如何停止后台的 FastCGI 进程:
1. 如果指定了 pidfile 属性,则可以这样:
kill `cat $PIDFILE`
其中 $PIDFILE 是你指定的 pidfile 选项。
要重启 Unix 上的后台 FactCGI 进程,可执行下列 shell 脚本:
#!/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 的设定:
1. 需要安装了 mod_fastcgi
2. 编辑 httpd.conf:
(1) 用 FastCGIExternalServer 指向 FastCGI 服务器的位置
可以用 socket 也可以用主机+端口的方式指定。例子:
# 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 这个文件是不需要存在的。其作用指示作为一个 URL 指示 Web 服务器哪些请求需要被 FastCGI 来处理。
(2) 用 mod_rewrite 来分派需要处理的 URL 到 FastCGI.
例子:
<VirtualHost 12.34.56.78>
ServerName example.com
DocumentRoot /home/user/public_html
Alias /media /home/user/python/django/contrib/admin/media
RewriteEngine On
RewriteRule ^/(media.*)$ /$1 [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^/(.*)$ /mysite.fcgi/$1 [QSA,L]
</VirtualHost>
这里指示的重写后的 url 就是上面 FastCGIExternalServer 中那个。
上述配置将不是 /media/ 开头的,或者指向不存在的文件的请求,转给了 FastCGI.
lighttpd 配置
lighttpd 天然的支持 FastCGI.
首先要确认你的 mod_fastcgi 在模块列表中,并且在 mod_rewrite 和 mod_access 后,在 mod_accesslog 前。
为了服务 admin media, 也许你还需要 mod_alias.
在 lighttpd 的配置文件中加如下一段:
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.*)$" => "$1",
"^/favicon\.ico$" => "/media/favicon.ico",
"^(/.*)$" => "/mysite.fcgi$1",
)
还可以在一个 lighttp 服务器上跑多个 Django. 只要为每一个应用指定一个独立的 FastCGI host.
如何在共享的 web hosting 上运行 Django / Apache:
编辑 .htaccess:
AddHandler fastcgi-script .fcgi
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ mysite.fcgi/$1 [QSA,L]
再写一个 mysite.fcgi 的可执行的脚本:
#!/usr/bin/python
import sys, os
# Add a custom Python path.
sys.path.insert(0, "/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")
在更新代码后,可以通过重新上传 mysite.fcgi 文件来指示 Apache 重启 Django 程序。
如果有 shell 权限,可以直接用 touch 命令改变时间戳:
touch mysite.fcgi