2011年3月23日

Perl CPANモジュールガイド

Perl関係で久しぶりに絶対に買わないと!と思える本がリリースされます。

「Perl CPANモジュールガイド」というタイトルで、CPANモジュールの解説書です。なかなかどのモジュールを使ったら良いか、分からないCPANモジュールですが、こうゆう本が有ると特に熱心なCPANマニアじゃなくても安心ですね!

編集後記ブログもいい感じです。

Perl CPANモジュールガイドPerl CPANモジュールガイド
冨田尚樹 タナカユカリ

ワークスコーポレーション 2011-04-08
売り上げランキング : 1864

Amazonで詳しく見る
by G-Tools

2011年3月19日

FastCGIを使ってみる

FastCGIの作り方を解説した日本語のサイトが意外と少ないので、調べるのに苦労しましたが、とりあえずまとめてみました。

でも必要な情報は結局全てFastCGIの公式サイトに載っているんですけどね。

FastCGIとは?

CGIはプログラミング言語を選ばない汎用性(一般的な標準入力・標準出力を使ったコマンドラインアプリケーションが作れれば何でもかまわない)が最大のメリットですが、ウェブブラウザからのリクエストの度にプロセスの生成と破棄が行われるため、オーバーヘッドが大きいというデメリットが有ります。

特にPerlの様なインタプリタ系言語では言語自体の実行環境が大きいため、プロセスの生成だけでも大きなオーバーヘッドです。加えて最近のWebアプリケーションではWebアプリケーションフレームワークや様々なライブラリが使われているため、それらのモジュールの読み込み・初期化も大きなオーバーヘッドになってきます。

しかし、Perlの起動や、モジュールの読み込み・初期化といった処理はどのリクエストでもやる事は同じです。これらの一連のリクエストの前処理がスキップできれば、リクエスト処理は大幅な速度向上が見込むことができます。

これらアプリケーションの起動時に一度だけ実行すれば良い様な処理内容を一度実行すれば、2回目以降はスキップできる様にするための仕組みがFastCGIです。

FastCGIの処理の仕組み

おさらいですが、PerlのCGIアプリケーションの場合、以下の図の様な処理イメージになります。

FastCGI-1

FastCGIは、一度起動したアプリケーションのプロセスがリクエスト処理終了後も残り続ける事で、CGIではリクエストの度に発生するプロセスの生成とアプリケーションの初期化をスキップし、リクエスト処理を高速化させます。

そのため、PerlのFastCGIアプリケーションの場合、以下の図様な処理イメージになります。

FastCGI-2.png

特に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をはじめlighttpdnginxといった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を勉強します。

2011年3月 7日

今、再びのCGI

自分のPerlの使い方と言えばほとんどが伝統的なテキスト処理がメインで、Webアプリケーションを作った事が無い。簡単なCGIをフレームワークも無しに作った事が有るくらい。セッション管理もログイン機能も無い、本当に簡単な機能を作っただけ。それも使っていたAPIの仕様変更に対応するのが面倒だったので、結局クローズしてしまった。

しかし、最近(でもないけど)話題のPlackのドキュメントを読むと、Web Serverの環境ごとの差異を吸収するインタフェースを提供すると書かれてあって、実際にどんな環境ごとの差異が有るのか知りたくなってきたので、そんな情報収集の記録です。あ、でも別にPlackの話題は出てきません。そしてCGIの作り方も出てきません。

今回はCGIのおさらい。

CGIとは?

CGIは、Common Gateway Interfaceの略。最も古典的な動的Web Siteを作るためのインタフェース規格。たいていのWeb Serverでサポートされている。

インタフェースの内容は極めてシンプルで、Web Browserからのリクエストを元に必要な情報(主にURIや、POSTメソッドのBODY部等)を環境変数や標準入力に格納し、CGIプログラムを起動し、結果(主にHTMLやJSON等)を標準出力から得る。

CGI

入力と、出力の規格を定めているだけなので、特定のプログラミング言語には依存しない。環境変数へアクセスでき、標準入力からの入力が処理でき、結果を標準出力へ出力できる言語であれば何でもかまわない(つまり、世の中ののたいていのプログラミング言語であれば、CGIプログラムは作れる、という事)。

一般的にはテキスト処理が得意な汎用言語であるPerlが多く使われる事が多い(最近はPythonやRubyも使われる)。

実際のCGIプログラム

最初に書いた通りCGIでは環境変数や標準入力の内容を元に処理を行うが、PerlではCGI.pmというモジュールが統一的なインタフェースを提供してくれる。

また、出力に関してもHTMLを生成するためにHTMLタグに対応したメソッドが提供してくれる。

実際のCGIプログラムは以下の通り。

cgi_test.cgi

#!/usr/bin/env perl

use strict;

use utf8;

use Encode;

use CGI;

my $cgi = CGI->new;


print $cgi->header(-charset=>'utf-8');

print encode('utf-8', $cgi->p("あなたのユーザーIDは" . 
                        $cgi->param(id) "です。");

print $cgi->end_html;

拡張子は一般的に、.cgiが使われる。また、実行権限を付与しておく。

$ chmod +x cgi_test.cgi

サーバの設定

最もよく使われるWeb Serverであるapacheであれば、設定ファイルのhttpd.confに以下の記述を行う。

1.CGI専用のディレクトリを用意する場合。
/usr/local/apache2/cgi-bin/配下は全てCGIプログラムとして扱われる(違えばエラー)。

ScriptAlias /cgi-bin/ /usr/local/apache2/cgi-bin/

2.特定の拡張子だけをCGIプログラムとして起動する場合。
/home/user/public_html配下に有る拡張子が.cgiのファイルがCGIプログラムとして扱われる。

<Directory /home/user/public_html>
Options +ExecCGI
AddHandler cgi-script .cgi
</Directory>

その他、CGIにまつわる事

  • たいていのレンタルサーバはCGI環境を提供され、Perlが使える。
  • レンタルサーバのPerlのバージョンは新しくても5.8.8。開発環境をローカルに準備するのが意外と大変(最近のOSではサポートされていないから)。
  • レンタルサーバではCコンパイラが提供されない事が多いので、CPANモジュールのインストールが大変(pure perlモジュールじゃないと実質無理)。
  • CGIモジュールを使ったHTML生成はちょっと複雑な画面を作ろうと思うと、すぐに可読性が低下する。よっぽどシンプルな画面じゃないとHTMLテンプレートモジュールを使うべき。
  • 言語に依存しない汎用的な機能なので、その分非常に遅い。リクエストの度にPerlインタプリタが起動するので、その分遅い。
  • たいていのWebアプリケーションフレームワークでサポートされている。

おわりに

次回はCGIよりもっと早いFastCGIを扱います。