2010/04/20(火)ApacheのRLimitMEMが効かない
CGI開発中についうっかり無限ループを生成するなんて経験のある人も多いと思いますが、つい最近2回連続でサーバごと落としてしまったので*1本格的に対策しました。
RLimitMEMとRLimitCPU
ApacheにはもともとCGIのメモリやCPU使用量を制限する設定があります。それがRLimitMEMとRLimitCPUです。
それぞれ「メモリ(リソース)使用量」と「CPU時間使用量を制限する」もので、制限値を超えた瞬間にプロセスを殺してくれます便利なものです。*2
# 256MB limit(unit Byte) RLimitMem 268435456 RLimitCPU 30
もちろんこれは設定していたのですが……。
RLimitMemが効かない
top コマンドで監視していいたら普通に500MBのメモリを食ってます。どうやら、RLimitMemやRLimitCPUが効かないようです。
- mod_perl / mod_perl2
- FastCGI(mod_fastcgi) / mod_fcgid
では効きません。ちょうどmod_fcgidを使用していました。Perl自体は別プロセスで起動しているので効くのかと思ったのですが、どうやら無効なようです(汗)。ちなみに通常CGIの他、SpeedyCGIは効きます。*3
Apache自体に制限を掛ける
Apache自体のメモリ消費量に制限をかければ、万が一無限ループなどで暴走してもサーバ落ちを防ぐことができます。Apache自体は落ちてしまいますが、サーバが落ちるよりは100倍マシです。
Apacheの起動スクリプト(シェルスクリプト)に
# 1GB limit(unit KByte) ulimit -v 1048576
と記述することで制限を加えることができます。
Ubuntu/Debian系の場合は /etc/apache2/envvars に ulimit を書き加えればよいようです。これでApache自体が落ちると思ったのですが、mod_fcgid の場合 fcgi プロセスのみが落ちてくれました。
ちょっと謎は残るけど、とりあえず目的は達成したのでこれで。