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

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用のライブラリを持ってきます。

$ sudo aptitude install libfcgi-dev

bin-path で指定した位置にバイナリを作ります。

$ cd /var/www
$ sudo mkdir fcgi-bin
$ cd fcgi-bin
$ sudo vim fcgi.c

fcgi.c の内容は次のとおりです。

</p>

<h1>include &lt;fcgi_stdio.h&gt;</h1>

<p>int main(int c, char** argv)
{
    int cnt = 0;
    while (FCGI_Accept() &gt;= 0)
        printf(&quot;Content-type: text/html\n\ncount=%d\n&quot;, ++cnt);
    return 0;
}

fcgi_stdio.h をインクルードすると、printf() などの標準ライブラリ関数が FastCGI のものに置き換えられ、FCGI_Accept() などの関数が使えるようになります。

このコードをビルドします。-lfcgi オプションで FastCGI へのリンクもお忘れなく。

$ sudo gcc -o test.fcgi test.c -lfcgi -Wall -O3
$ sudo chmod a+rx test.fcgi

念の為、全ての権限に rx を付与しています。
最後に設定を反映させる為、lighttpd を再起動します。

$ sudo /etc/init.d/lighttpd restart

lighttpd.conf の fastcgi.server で設定したパスにアクセスしてみます。

$ curl http://127.0.0.1/fcgi
count=1

何度もアクセスしてみて、count の値が増えつづければプロセスが常駐していることが分かります。

$ 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

投稿者:

dyama

佐世保のシステムエンジニアです。詳しいプロフィールやこのブログについてはこちらをご覧ください。

コメントを残す

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

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください