リリースしてからバグはいくつか見つかったけど、それ以外は安定稼動していたわけですが、エンドからサイトが激重で使えたもんじゃないとクレームが。
環境
・CentOS 5
・Apache 2.2.8 + mod_proxy_balancer + mongrel 1.1.2
・Ruby 1.8.4
・Rails 1.2.6
・RMagick 1.13.0
・ImageMagick 6.0.7.1-17
実際見てみると激しく重い。
こりゃ大変だとあわてて調査したところ、メモリ使用量が激増。swapまで目一杯使っているわけです。
とりあえずmongrelがとんでもないことになっているので再起動で解決。
その後、しばらく監視体制を敷いていろいろ調査してみたのですが、サービス開始して1ヶ月ほどで、まだたいした宣伝もしてないということで1日100件程度しかアクセスがないし、Google Botやらのクローラがものすごい勢いで増えて来てるくらいだけど、それ含めても重くなる原因にはちょっと足らない。この程度で重くなるっていうのはちょっとありえない。
開発前にベンチマークとったときも対して問題にはならなかったし。
さらに日を重ねて調べてみると、調査開始にはほとんど使ってなかったswapが半分以上圧迫されているので、やはりアプリのどこかに問題があるらしい。
ノーチェックなのはライブラリか?
Rubyで画像を扱う際に利用する定番「ImageMagick + RMagick」を利用してみたてるわけですが、どうやらこいつが怪しい。
調べてみると、RMagickにメモリーリークのバグがあるらしい。
http://techno.hippy.jp/rorwiki/?How+to+debug+memory+consumption+problems+or+memory+leaks
仕様って話もあるけど、その辺は詳しく調べてないのでよくわからない。
def run_gc
fDisabled = GC.enable
GC.start
GC.disable if fDisabled
end
こいつを画像をいじった後に呼べば解決するらしい。
実際にコードを埋め込みベンチをとってみると、確かにメモリの増加量がちょっと減っているみたい。
でもベンチ結果を見る限り完全に開放されるわけじゃないっぽいので、サーバが止まるのは時間の問題ってことみたい。
それじゃ困るということで、解決策を考えた。
処理的には
・今まで
PCの管理ツールから画像をアップロードして元データをDBに格納
↓
RMagickで携帯用にgif、pngに横320pxで変換して画像ファイルを配置
↓
携帯からのアクセス時に解像度をチェック
↓
解像度の横幅がピッタリな画像ファイルがあるかチェック
↓
存在しない場合は解像度をあわせた画像をDBの画像データから生成し表示
・解決後
PCの管理ツールから画像をアップロードして元データをDBに格納
↓
RMagickで携帯用にgif、pngのいろんな解像度の画像ファイルを配置
↓
携帯からのアクセス時に解像度をチェック
↓
ちょうどいいサイズの画像を表示
それと、一日一回cronでmongrelを再起動。
という感じになりました。
まぁ元の処理がひどいけど、結局はRMagickを呼ぶだけでメモリを確保しちゃうっぽいので、アクセスが多い携帯側ではRMagickを利用しない方向に急遽改修。
あとはあんまりしたくはないけど、mongrelの再起動をしてメモリを力技で開放が一番いいみたいです。
以上です。