Posted at

Mojoliciousアプリをmod_perlでデプロイする

More than 5 years have passed since last update.


mod_perlってまだいけるの?

PlackベースのStarmanやStarlet、そしてMonocerosなどの優秀なウェブサーバ全盛時代、そしてApacheよりもNginxのほうが流行な昨今、Apache mod_perlが良い場合ってあるの?と聞かれることがあります。


  • mod_perl は今も開発が進められている

  • とても安定している

  • Apacheのノウハウがある技術者がそのノウハウを活用できる

  • リバースプロキシをしたりしない分、 ミドルウェアとして起動されるデーモンが一種類減ることになり、ある種の案件では喜ばれる 場合がある


mod_perl環境でMojoliciousアプリをデプロイする

これは簡単な話で、MojoliciousはPSGI環境に対応しているので、Plack::Handler::Apache2 でデプロイしてやると良いです。

今回は Apache2.x と mod_perl2 のみの話です。v1も同じような感じですが、あまり Apache1.3 と mod_perl1 での Plack の活用事例がないので、逆に枯れていないのではないかという欠点もあります。

Apacheの設定ファイルに以下のように、Mojoliciousの設定ファルを指定してやるだけです。まさにplackup感覚。

  <Location />

SetHandler perl-script
PerlResponseHandler Plack::Handler::Apache2
PerlSetVar psgi_app /path/to/app.psgi
</Location>

app.psgi の作り方は、Mojoliciousアドベントカレンダー1日目のMojoliciousの様々な立ち上げ方を参照ください。

拙作ですがModPerl::PSGI というものもあり、これはPlackとは違うApache mod_perl上のPSGI実装となっています。設定も上記とほぼ同様に可能となっております。

私の手元ではテストが足りていないのですが、フルスタックで全てを搭載したMojoliciousではModPerl::PSGIが作るPSGI環境でも使えると考えています。Plackが依存するモジュールの多さがネックとなる特集な案件や環境では、Perl5.8コアとmod_perl2コアのみにしか依存を持たないModPerl::PSGIの採用を検討してみるとよいかもしれません。質問などありましたらTwitter @xtetsuji などでお知らせください。


mod_perl環境のMojoliciousアプリの注意点

Apache の prefork MPM を使っている場合、Mojoliciousのhypnotoadとは違って、1プロセスは同時に1リクエストしか同時に処理することができません。なのでApacheの設定であるMaxSpareServersなどの設定値を適切に設定する必要があります。


プロセスが肥大化する場合の対策法

巨大なファイルを扱ったりしたあとの場合、解放されないメモリがあったり、mod_perlと一体となっているApacheのpreforkした子プロセスのメモリが肥大化してサーバのメモリを食いつぶしたりする場合があります。

常套手段ではありますが一つの対策として、ApacheのMaxRequestsPerChildに最大リクエスト処理数を設定する方法があります。たくさんのリクエストを処理すればするほどプロセスサイズが肥大化しているだろうという仮定によります。

その他にmod_perl2に標準付属しているApache2::SizeLimitを使う手があります。Apacheのpreforkされた子プロセスがリクエスト処理ごとに、自らのサイズを計って規定以上の大きさの場合は自分自身のプロセスを終了します(child terminate)。Apacheの親プロセスは、子プロセスが足りなくなれば新しい子プロセスを充当します。詳細はApache2::SizeLimitのperldocを参照ください。