coding, photo, plant and demo

*FastCGI導入

tech btz 20100529 150559
FastCGIを導入した。
最初のリクエスト完了までに250msは掛かっていたのが、40ms程度になった *0
また、レンダリング完了まで2~3秒掛かっていたのが、1秒を切った *1
これは予想以上に劇的な改善。

簡単にFastCGIとapache2+rubyの場合の導入手順をメモっておく。

FastCGIとは何か

まず通常のcgiには大きな問題がある。
御存知の通りcgiを呼び出される度にプロセスやスクリプトの初期化が走ってしまうことだ。

このサイトの場合、

  • linuxがプロセスを新しく作る
  • その中でrubyが起動する
  • 指定されたスクリプト及び、その中のrequireを次々と読み込む
    • cgi,session,mysql等のモジュールがロードされる。勿論rbの解釈だけでなく.soも読み込まれる
  • dbを開く

と言った高コストな初期化処理がリクエストの度に走る。
仮に本体の処理は、sessionの情報に従ってキャッシュされた値を返すだけ、という非常に単純なものであったとしても、だ。
とんでもない無駄。

なので、初期化を終わらせたrubyを待機させておき、リクエスト毎に起こせば激速になる。

ということをやる仕組みがFastCGI。

さらに過激に高速化する手としては、serverと同一プロセスで動かしてしまう方法がある。apacheだとmod_perlとかmod_rubyを使えばできるし、PHPだと標準がそうなっている。ただ、serverが沢山起動したときに無駄にメモリを食うし、この場合プロセス間通信のコストは無視して良いので、そこまで拘らなくても良いと思う。
その手の比較は、

Perl CGIのキャッシュ環境
http://adiary.blog.abk.nu/068

が詳しかった。
speedy便利だなあ。

apache2+ruby+FastCGI

さて、では使い方。apache2+rubyの場合。

まずはインストールとapache2の再起動。
$ sudo apt-get install libapache2-mod-fcgid
$ sudo apt-get install libfcgi-ruby
$ sudo /etc/init.d/apache2 restart

.htaccessに.rbをFastCGIで動かすように指定。
AddHandler fcgid-script .rb
いきなり移行するのは怖い場合は.frb等にする。

後は.rbの修正。CGIモジュールを使っているなら置換えは簡単。
  1. 1# 初期化
  2. 2....
  3. 3
  4. 4FCGI.each_cgi do |cgi|
  5. 5 # 本体
  6. 6 ....
  7. 7 # cgiはCGIを派生したものが返ってくる
  8. 8 # よって、CGI::Session.new(cgi)などもそのまま動く
  9. 9end
FCGIは賢いので、そのまま普通のcgiでも動くからデバッグが楽。

雑感

このサイトの場合、特に効いたのが画像の取得。
画像の取得もpermissionの確認をするため、cgi,session,mysqlの初期化が毎回走る。画像を張り付けまくるととんでもないことになってた。
これは完全な設計ミスだわ。publicな画像は直リンできる仕組みにすべきだった。
*0 : LAN内での計測
*1 : Google Chromeにて計測