こんにちは satoです。
現在 Ruby on Rails で書かれた アプリケーションの 一部のURIを高速化するために、lighttpd + FastCGI で 書き直しています。FastCGI は あらかじめ プロセスを常駐させておき、リクエストが来た際に、常駐しているプロセスに Unix domain socket あるいは TCP/IP で通信を行い プロセス起動時のオーバーヘッドを無くすことにより、処理を高速化します。今回は lighttpd + FastCGI で Hello word を作る 解説します。
まず lighttpd と FastCGI を 用意します 環境はCentOS5です。
lighttpd: yum install lighttpd FastCGI: wget http://www.fastcgi.com/dist/fcgi.tar.gz tar xzvf fcgi-2.4.0.tar.gz cd fcgi-2.4.0 make sudo make install
lighttpd の設定ファイル ligttpd.conf を編集します
vi /etc/lighttpd/lighttpd.conf server.modules = ( "mod_access", "mod_fastcgi", ""mod_accesslog") (中略) fastcgi.server = ( "/" => ( ("socket" => "/dev/shm/test.fcgi.socket.1", "check-local" => "disable") ) )
簡単に説明しますと、mod_fastcgiモジュールを有効にして、 / に来たリクエストを /dev/shm/test.fcgi.socket.1 に送ります
fastcgi の test.cpp のソースは以下です。
#include "fcgi_config.h" #include#ifdef HAVE_UNISTD_H #include #endif #ifdef _WIN32 #include #else extern char **environ; #endif #include "fcgi_stdio.h" int main () { int count = 0; while (FCGI_Accept() >= 0) { printf("Content-type: text/html\r\n" "\r\n" " FastCGI HelloWorld " "FastCGI HelloWorld
\n" "Request number %d, Process ID: %d\n", ++count, getpid()); } return 0; }
簡単に解説しますと FCGI_Accept() は システムコール の accept と似たような感じでリクエストが発生すると 待ち状態から ループに入ります。次にprintfですが これは #include "fcgi_stdio.h" の中で
#define printf FCGI_printf
となっていて 実際には FCGI_printfが 呼ばれます。 FCGI_printf は 最終的には システムコールの write を呼んで 通信などを行います(windowsでは send関数)。あとは content-type を出力して おしまいです。fcgi はそのまま終了しないで FCGI_Accept に戻り、リクエストがあるのを待ちます
g++ -o test.fcgi test.c -lfcgi
として test.fcgi の バイナリができたら、lighttpd に付属している spawn-fcgi というツールで fcgiを立ち上げます
sudo spawn-fcgi -f ./test.fcgi -s /dev/shm/test.fcgi.socket.1 2>&1 > /dev/null
これでアクセスできるはずです。何度もアクセスすると プロセスは終了しないので、プロセスIDは変わっていないのに、count は増えているかと思います。mysqlのconnectや設定ファイルの読み出しは ループの外で行いましょう。
勉強会の時にも出た質問なんですが、Apache module で作らない理由は、Apache にしか使用できないということと、そのサーバを他用途で使用するときに mod_test が読まれていると 無駄に connectionを張ってしまったりするためです。