mod_wsgi: WSGIDaemonProcess

mod_wsgi には embeded mode (Apache のプロセスと一心同体) とdaemon mode があるのですが、小さなWSGIスクリプト以外では daemon mode を使った方が応用が利きます。
そこで、mod_wsgidaemon mode について調べてみました。

まず、 mod_wsgidaemon mode (以降、WSGIDaemonProcess で表します) を図で表すと次のようになります(たぶん)。WSGIDaemonProcess と Apache は Proxy でゆるくつながっていて、設定ファイルでの WSGIDaemonProcess 宣言1つにつき複数の DaemonProcess が存在し、それぞれにまた複数のスレッドがぶら下がっています。

以下、 WSGIDaemonProcess の特徴です。

  • Apache のプロセスとは別に、WSGIDaemon 用のプロセスが立ち上がるので、そのプロセスを再起動しさえすれば、Python 環境を再起動することができます。(embeded mode の場合、Apache を再起動しないとPython環境は再起動されません)
  • WSGIReloadMechanism を "Process" に設定しておくと、DaemonProcess で起動される wsgi スクリプト (index.wsgi とか) のファイル内容が変更されると、自動的にプロセスが再起動 (つまり、python sub interpreter が再起動) して、Python 環境が再起動されます。(embeded mode の場合、wsgi スクリプトを書き換えるとスクリプト自体は再読み込みされますが、Python 環境は再起動されません。すなわち、Django などのフレームワークへの橋渡しとしてwsgi スクリプトを利用していた場合、Django プロジェクトの本体を改変しても、その内容は反映されないことになります。)
  • WSGIDaemon 用のプロセスは、実行するUNIXユーザを指定して起動することができます。(前提条件: Apache が root 権限で起動されていること)
  • WSGIDaemonProcess の設定で maximum_requests を指定しておくと、指定回数の request が発生したら、自動的にプロセスを再起動してくれます。これは、意図しないメモリリークに対する対策として便利です。


参考までに、WSGIDaemonProcess を用いた設定例を示します。(作者の Graham Dumpleton 氏が ML で紹介していたホスティングサーバ用の設定を一部改編しました)

<VirtualHost *:80>

    ServerName www.site.com
    DocumentRoot /usr/local/sites/www.site.com/htdocs

    ErrorLog "/usr/local/sites/www.site.com/logs/error_log"
    CustomLog "/usr/local/sites/www.site.com/logs/access_log" common
    LogLevel info

    WSGIDaemonProcess jack-1 user=jack processes=2 threads=25 maximum_requests=10000 \
      python-path=/usr/local/sites/www.site.com/lib/python2.5/site-packages
    WSGIProcessGroup jack-1
    WSGIReloadMechanism Process

    <Directory /usr/local/sites/www.site.com/htdocs>
      Order deny,allow
      Allow from all
      Options MultiViews ExecCGI SymLinksIfOwnerMatch

      AddHandler wsgi-script .wsgi

      RewriteEngine On
      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteRule ^(.*)$ /site.wsgi/$1 [QSA,PT,L]
    </Directory>

</VirtualHost>

普通のcgiphp 同様、wsgi 拡張子のファイルへのアクセスでWSGIアプリケーションが実行されます。また、URLに対応するファイルが見つからなかったばあには、 site.wsgi が実行されます。

なお、mod_wsgi のマニュアルには、リファレンスはもちろんのこと、 virtualenv を利用する方法や .htaccess に一部設定を委譲する方法など、豊富な情報があります。

(追記)
なお、Pylons のデバッガを利用したい場合は WSGIDaemonProcess のプロセス数を 1 にしてください。マルチプロセスだとデバッガを利用することができません。また、プロセス数を 1 にするときには "processes=1" とするのではなく、 "processes" オプション自体を指定しないようにしてください。processes オプションが設定されていると、プロセス数が1でもマルチスレッドとして処理されます。
(参考: http://code.google.com/p/modwsgi/wiki/DebuggingTechniques#Browser_Based_Debugger

(追記2)
同じ WSGIDaemonProcess を利用していても、別の場所で宣言されていれば Python Sub Interpreter は共有されません。そのため、VirtualHost の外で WSGIDaemonProcess を宣言しておいて、複数のVirtualHost で同じWSGIDaemonProcess を利用することができます(図画間違っていたので修正しました)。このようにして、利用するプロセス数を制限することができますが、同一プロセス上で複数のInterpreter が実行されることを想定していない、いくつかのパッケージで不具合が発生することがあるようです。(GILを使っているもの、psycopg2 の以前のバージョンなど)
* 参考: http://code.google.com/p/modwsgi/wiki/ApplicationIssues#Multiple_Python_Sub_Interpreters

posted by id:junya_hayashi