FastCGIの作り方を解説した日本語のサイトが意外と少ないので、調べるのに苦労しましたが、とりあえずまとめてみました。
でも必要な情報は結局全てFastCGIの公式サイトに載っているんですけどね。
FastCGIとは?
CGIはプログラミング言語を選ばない汎用性(一般的な標準入力・標準出力を使ったコマンドラインアプリケーションが作れれば何でもかまわない)が最大のメリットですが、ウェブブラウザからのリクエストの度にプロセスの生成と破棄が行われるため、オーバーヘッドが大きいというデメリットが有ります。
特にPerlの様なインタプリタ系言語では言語自体の実行環境が大きいため、プロセスの生成だけでも大きなオーバーヘッドです。加えて最近のWebアプリケーションではWebアプリケーションフレームワークや様々なライブラリが使われているため、それらのモジュールの読み込み・初期化も大きなオーバーヘッドになってきます。
しかし、Perlの起動や、モジュールの読み込み・初期化といった処理はどのリクエストでもやる事は同じです。これらの一連のリクエストの前処理がスキップできれば、リクエスト処理は大幅な速度向上が見込むことができます。
これらアプリケーションの起動時に一度だけ実行すれば良い様な処理内容を一度実行すれば、2回目以降はスキップできる様にするための仕組みがFastCGIです。
FastCGIの処理の仕組み
おさらいですが、PerlのCGIアプリケーションの場合、以下の図の様な処理イメージになります。
FastCGIは、一度起動したアプリケーションのプロセスがリクエスト処理終了後も残り続ける事で、CGIではリクエストの度に発生するプロセスの生成とアプリケーションの初期化をスキップし、リクエスト処理を高速化させます。
そのため、PerlのFastCGIアプリケーションの場合、以下の図様な処理イメージになります。
特にPerlの様なインタプリタ系言語では処理系の起動自体がかなり重い事も有り、速度向上に劇的な効果が有ります。
FastCGIアプリケーション
PerlではFastCGIを扱うためのモジュールがいくつか有るが、ここでは一例としてFCGIモジュールを使ったアプリケーションのサンプルを紹介します。
fcgi_test.fcgi
#!/usr/local/bin/perl
# 初期化処理
use strict;
use warnings;
use utf8;
use Encode;
use Time::Piece;
use FCGI;
my $count = 0;
my $request = FCGI::Request();
my $time1 = localtime;
print encode("utf-8", "アプリケーション起動時刻:" . $time1);
# リクエスト処理
while($request->Accept() >= 0) {
my $time2 = localtime;
print("Content-type: text/html; charset=utf-8\n\n");
print encode("utf-8", "リクエスト処理時刻" . $time2);
}
「$request->Accept」はhttpのリクエストが来る迄は返り値を返さず、待ち状態になります。リクエストを受け取ると、0以上の返り値を返し、whileループの中の実際のリクエスト処理が実行されます。
つまり、プロセスが残ると言っても複雑な仕掛けが有る訳ではなく、FCGIアプリケーションプログラム自身が自分でループを回しながらリクエストを待っているだけという意外とシンプルな仕組みです。
FastCGIを使うためのサーバの設定
仕組みが分かった所で、実際に動作させるための環境設定です。FastCGIは、Apacheをはじめlighttpd、nginxといったWeb Serverでサポートされていますが、ここではApacheで実行するための設定例を紹介します。
mod_fcgidをセットアップする
ApacheでFastCGIを扱える様にするモジュールにはmod_fcgidと、mod_fastcgiの2種類が有ります。ここではmod_fcgidを使います。
Mac OS X Snow Leopardに最初からインストールされているApacheにmod_fcgidモジュールをインストールするためには、ここからダウンロードしたファイルを解凍し、デフォルトの設定でインストールするだけです。
$ wget http://ftp.riken.jp/net/apache//httpd/mod_fcgid/mod_fcgid-2.3.6.tar.gz
$ tar xvf mod_fcgid-2.3.6.tar.gz
$ cd mod_fcgid-2.3.6
$ ./configure.apxs
$ make
$ sudo make install
mod_fcgidのロード設定は、インストール時に自動的にhttpd.confに以下の様に追加されます(Mac OS X Snow Leopardでは、/private/etc/apache2/httpd.confに追加)。
LoadModule fcgid_module libexec/apache2/mod_fcgid.so
fcgiライブラリをセットアップする
mod_fcgidはあくまでhttpのリクエストをFastCGIアプリケーションにディスパッチする機能しかありません。実際にFastCGIアプリケーションのプロセスを起動するためには、FastCGIという名前のライブラリをインストールする必要が有ります。
$ wget http://www.fastcgi.com/dist/fcgi.tar.gz
$ tar xvf fcgi-2.4.0.tar.gz
$ cd fcgi-2.4.0
$ ./configure
$ make
$ sudo make install
これで必要なライブラリがインストールされます(その他にC言語用のヘッダファイルなども同時にインストールされます)。
mod_fcgidの設定を行う
実際にFCGIアプリケーションが起動するためにはFCGIアプリケーションの拡張子をmod_fcgidの提供するハンドラに登録する必要が有ります。
ここではFCGIアプリケーションの拡張子を.fcgiとします。Perlで書いたスクリプトの拡張子を.fcgiで保存します。
Mac OS X Snow Leopardでは、apacheの設定はユーザー毎に分かれており、/etc/apache/user/xxx.conf(xxxはユーザー名)に保存されています。ここにFastCGIアプリケーションを起動させるための設定を追加します。
ここではcgiも含めて下記の設定にします。
<Directory "/Users/xxx/Sites/">
Options Indexes MultiViews ExecCGI
AllowOverride None
Order allow,deny
Allow from all
AddHandler cgi-script .cgi
AddHandler fcgid-script .fcgi
</Directory>
ユーザーディレクトリのSiteディレクトリ配下に上記のスクリプトを配置して、システム環境設定の共有から「Web共有」を「入」にします。
アドレスが表示されるので、そのアドレス+スクリプト名をURLに指定します。
例えば「http://192.1681.1.xxx/~xxx/fcgi_test.fcgi」みたいなアドレスになるはずです。
おわりに
意外とシンプルな仕組みのFastCGIですが、効果は絶大。もっと奥が深いんですが、まずはここまで
次はmod_perlを勉強します。