FastCGI(fcgi)とは、通常のCGIのようにリクエストが発生する度に起動、実行される仕組みではなく、一度起動したら起動しっぱなしでリクエストを処理するタイプのCGIです。常にメモリの上に乗っているので、メモリを食いますが、大量のリクエストをオーバーヘッドなしで処理できる利点があります。
FastCGIでバイナリプログラムを実行するケースのパフォーマンスはなかなか良いらしいので、我が家のlighttpdサーバにも導入してみることにしました。
久しぶりに lighttpd.conf を覗いてみると、モジュール読み込み部分に既に mod_fastcgi が登録されていました。(そう言えば、以前 trac を動かしてみた際に FastCGI を使ってたっけ…)
server.modules = ( "mod_access", "mod_alias", "mod_accesslog", "mod_compress", "mod_redirect", "mod_expire", "mod_fastcgi" (略) )
こんな感じです。次に、FastCGIの設定を行います。
fastcgi.server = ( "/fcgi" => ( "fcgi" => ( "socket" => "/var/run/lighttpd/fcgi.socket", "check-local" => "disable", "bin-path" => "/var/www/fcgi-bin/test.fcgi", "min-procs" => 1, "max-procs" => 2 ) ) )
bin-path には、これから準備するバイナリのパスを指定しています。
我が家では、上の fcgi の設定に加えて、trac の設定もしてあります。
次にバイナリの用意です。FastCGI用のライブラリを持ってきます。
[bash]
$ sudo aptitude install libfcgi-dev
[/bash]
bin-path で指定した位置にバイナリを作ります。
[bash]
$ cd /var/www
$ sudo mkdir fcgi-bin
$ cd fcgi-bin
$ sudo vim fcgi.c
[/bash]
fcgi.c の内容は次のとおりです。
[cpp]
include <fcgi_stdio.h>
int main(int c, char** argv)
{
int cnt = 0;
while (FCGI_Accept() >= 0)
printf("Content-type: text/html\n\ncount=%d\n", ++cnt);
return 0;
}
[/cpp]
fcgi_stdio.h をインクルードすると、printf() などの標準ライブラリ関数が FastCGI のものに置き換えられ、FCGI_Accept() などの関数が使えるようになります。
このコードをビルドします。-lfcgi オプションで FastCGI へのリンクもお忘れなく。
[bash]
$ sudo gcc -o test.fcgi test.c -lfcgi -Wall -O3
$ sudo chmod a+rx test.fcgi
[/bash]
念の為、全ての権限に rx を付与しています。
最後に設定を反映させる為、lighttpd を再起動します。
[bash]
$ sudo /etc/init.d/lighttpd restart
[/bash]
lighttpd.conf の fastcgi.server で設定したパスにアクセスしてみます。
[bash]
$ curl http://127.0.0.1/fcgi
count=1
[/bash]
何度もアクセスしてみて、count の値が増えつづければプロセスが常駐していることが分かります。
[bash]
$ curl http://127.0.0.1/fcgi
count=2
$ curl http://127.0.0.1/fcgi
count=3
$ curl http://127.0.0.1/fcgi
count=4
[/bash]