fastcgi-nginx vs mod_wsgi-apache
"mod_python 終了のお知らせ" を受け、もともとリソース不足だった既存の Django アプリケーション郡のサーバをリプレイスすることにしました。リプレイス要件↓
- パフォーマンスが高いのにしたい
- アプリケーションの変更は必要最小限にしたい
- URL 類は既存のアプリケーションを引継ぐ: 複数プロジェクトをサブディレクトリーで運用していて、 "django.root" で複数プロジェクトを切り分けている
環境設定について
これは apache - mod_wsgi が簡単すぎます。
nginx - fastcgi
nginx - fastcgi 構成の場合は、init.d への登録、 daemontools を利用 (弊社は mod_python 以外はこれ)。
nginx の設定
/etc/nginx/fastcgi_params
fastcgi_read_timeout 180; send_timeout 180; fastcgi_param QUERY_STRING $query_string; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_param PATH_INFO $fastcgi_script_name; fastcgi_param SERVER_PROTOCOL $server_protocol; fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; fastcgi_param REMOTE_ADDR $remote_addr; fastcgi_param REMOTE_PORT $remote_port; fastcgi_param SERVER_ADDR $server_addr; fastcgi_param SERVER_PORT $server_port; fastcgi_param SERVER_NAME $server_name; fastcgi_pass_header Authorization; fastcgi_intercept_errors off;
/etc/nginx/sites-enabled/default
server {
listen 80;
server_name example.com;
access_log /var/log/nginx/example.com.access.log;
# No www ! <- www を付けたくない場合の設定
if ($host = 'www.example.com' ) {
rewrite ^/(.*)$ http://example.com/$1 permanent;
}
# Django の設定 <- 各 Django プロジェクトはポートで分ける
location / {
include /etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:8080;
}
# Admin sites の設定 <- ローカルからに限定する
location /admin {
include /etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:8080;
allow [LOCAL_IP_ADDRESS];
deny all;
}
# Static Files
location /static {
root /path/to/staticfiles;
access_log off; # アクセスログいらない
}
# Admin medias
location /media {
root /path/to/django/contrib/admin/media;
access_log off; # アクセスログいらない
}
}
fastcgi の起動を init.d に登録
Django FastCGI init.d script for Linux を参考に、init.d スクリプトを作成し、反映する。
update-rc.d /etc/init.d/fastcgi defaults
daemontools の設定
# パッケージ名は daemontools or svtools のいずれか sudo aptitude install daemontools daemontools-run
プロジェクト毎に、デーモンツールを作成する。
/etc/service/[PROJECT]/run
#!/bin/sh
#
#### SERVER SPECIFIC CONFIGURATION
SITE=[PROJECT]
HOST=127.0.0.1
PORT=[PORT]
SITES_PATH=/var/django
ENVIRONMENT_PATH=$SITES_PATH/environment
RUNFILES_PATH=/var/run/django
RUN_AS=www-data
MAXREQUESTS=1000
#### DO NOT CHANGE ANYTHING AFTER THIS LINE!
#
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DESC="[PROJECT DESCRIPTION]"
cd $SITES_PATH/$SITE
# find python binary to use
if [ -f $ENVIRONMENT_PATH/$SITE/bin/python ]; then
PYTHON=$ENVIRONMENT_PATH/$SITE/bin/python
else
PYTHON=`which python`
fi
exec 2>&1
exec setuidgid $RUN_AS \
/usr/bin/env -- $PYTHON \
$SITES_PATH/$SITE/manage.py runfcgi \
protocol=fcgi method=threaded maxrequests=$MAXREQUESTS \
host=$HOST port=$PORT \
pidfile=$RUNFILES_PATH/$SITE.pid \
daemonize=false
chmod -R 777 $RUNFILES_PATH
mod_wsgi - apache
wsgi 用スクリプトの作成
各 Django アプリケーションごとに作成します。settings.py と同一階層に置くことを前提。
#!/usr/bin/python # -*- encoding: utf-8 -*- # wsgi_handler.py import sys import os # print デバッグとかしてるとこけるから、追加しちゃった。 sys.stdout = sys.stderr sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/..') os.environ['DJANGO_SETTINGS_MODULE'] = '[PROJECT].settings' import django.core.handlers.wsgi application = django.core.handlers.wsgi.WSGIHandler()
mod_wsgi の設定
sudo aptitude install libapache2-mod-wsgi
<VirtualHost *:80>
ServerAdmin mail@example.com
ServerName example.com
DocumentRoot /var/www
# Django settings
WSGIScriptAlias / /path/to/project/wsgi_handler.py
ErrorLog /var/log/apache2/error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog /var/log/apache2/access.log combined
</VirtualHost>
daemon mode で起動したい場合の設定は、id:pyxis-dev さんのサイトが参考になります。私も daemon mode で運用しています。
パフォーマンスについて
結論から言うと、fastcgi も mod_wsgi も uwsgi もパフォーマンスに大きな差はありません (mod_python よりは早い) でした。パフォーマンスの差異については、 id:perezvon さんや Alexander Solovyov さんのサイト (英語) 等も参考になります。私がテストした環境だと、初回アクセス時のみ fastcgi の方が若干早かったですが、やはりその後は誤差の範囲内です。
mod_python からの移行について (URL とか)
前述のように、複数の Django プロジェクトをサブディレクトリで運用している場合は、 mod_wsgi の方が簡単です。 mod_python でいうところの "django.root" は mod_wsgi では以下のように設定できます。
# mod_python
<Location "/mysite/">
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
PythonOption django.root /mysite
PythonDebug On
</Location>
<Location "/mysite2/">
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite2.settings
PythonOption django.root /mysite2
PythonDebug On
</Location>
# mod_wsgi
<VirtualHost *:80>
WSGIScriptAlias /mysite /path/to/django/mysite/wsgi_handler.py
WSGIScriptAlias /mysite2 /path/to/django/mysite2/wsgi_handler.py
</VirtualHost>
fastcgi の場合は、rewrite の利用や、FORCE_SCRIPT_NAME で置き換えるか、 urls.py を書き換える必要があります。めんどい・・・。
ということで mod_wsgi を使うことにしましたよ!
コメント
コメントを投稿