FastCGI+lighttpd で C プログラムを動かす

投稿者: | 2012年11月22日

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]

コメントを残す

メールアドレスが公開されることはありません。