ajp-wsgiでDjangoを動かす

ajp-wsgiAJPプロトコルでWSGIアプリケーションを動かすためのゲートウェイサーバ。flupと同じようなもの。

ajp-wsgiとflupは作者も同じだし、flupもAJPをサポートしているけど、ajp-wsgiはすべてCで書かれているから、flupより速いらしい。作者自身が「もうflupなんて使わねーよww」(意訳)と書いているのを読んだ記憶がある。

というわけで、ずっとflupからajp-wsgiに乗り換えたかったのだが、「AJPプロトコルだとフロントはApacheを使わないといけないのか?」と思うと二の足を踏んでいた。


ところが今日、lighttpd 1.5にはAJPプロトコルのProxyがあるということを知り、さっそく試してみた。

lighttpd 1.5

Subversionでソースを取得してビルド。

$ svn co svn://svn.lighttpd.net/lighttpd/trunk lighttpd 
$ cd lighttpd
$ ./configure --prefix=/usr/local/lighttpd-1.5.0
$ make
$ sudo make install

CentOS 5.0とFedora Core 7でビルドしてみたけど、glib2-develとpcre-develがいるかも。

$ sudo yum install glib2-devel pcre-devel

ajp-wsgi

$ curl -O http://www.saddi.com/software/ajp-wsgi/dist/ajp-wsgi-1.0.tar.bz2
$ bzip2 -dc ajp-wsgi-1.0.tar.bz2 | tar xvf
$ cd ajp-wsgi-1.0
$ python configure.py
$ make
$ ./ajp-wsgi -V
ajp-wsgi 1.0

Djangoを動かす

テストしてみたいだけなので、次のような簡単なlighttpdの設定ファイルを用意して、ログインユーザの権限でフォアグラウンドで動かしてみる。

mimetype.assign             = (
  ".gif"          =>      "image/gif",
  ".jpg"          =>      "image/jpeg",
  ".jpeg"         =>      "image/jpeg",
  ".png"          =>      "image/png",
  ""              =>      "application/octet-stream",
 )

server.port          = 5000

server.modules = (
  "mod_proxy_core",
  "mod_proxy_backend_ajp13"
)

server.document-root = "/path/to/django/media/root"
$HTTP["url"] !~ "\.(?:jpg|png|gif)$" {
        proxy-core.balancer = "round-robin"
        proxy-core.protocol = "ajp13"
        proxy-core.backends = ("localhost:8009")
}

lighttpdを起動。

$ /usr/local/lighttpd-1.5.0/sbin/lighttpd -D -f lighttpd.conf
mod_proxy_core_address.c.156: (trace) resolving localhost on port 8009
log.c.142: (trace) server startedp

次にDjangoのAJPプロセスを立ち上げる。次のような起動用のスクリプトを自分で用意しておく。僕はSQLAlchemy+Djangoなアプリで試してみたのでこれだけで十分だったけど、本当はモデルのvalidationがいるかもしれない。

# runajp.py
from django.core.handlers.wsgi import WSGIHandler
app = WSGIHandler()

このスクリプトをrunajp.pyとして保存したならば、ajp-wsgiコマンドを使ってプロセスを起動する。

$ DJANGO_SETTINGS_MODULE=myproject.settings ajp-wsgi runajp app

myprojectがライブラリ検索パスに入っていなくてはいけないので注意すること。入っていないならば、PYTHONPATHを設定するなどの方法を使う。

$ export PYTHONPATH=/path/to/myproject
$ export DJANGO_SETTINGS_MODULE=myproject.settings
$ ajp-wsgi runajp app

これだけで普通にDjangoアプリがajp-wsgilighttpd 1.5で動く。flupでFastCGI/SCGI/AJPよりもずっとシンプルな感じがする。

肝心の実行速度だが、体感ではまったく変わらない。後でベンチマークをとってみないといけない。