いくつかの主だった実装ができあがりました。当初ToDoにあげていたインメモリなセッション管理、mod_perlとCGI互換のサーブレット?コンテナ、ロギングなどなど。あと一応SF.JPに乗っけました。
Net-AJP13改めAtami(熱海) Application Server
というわけで前のエントリからバージョン番号が小さく0.0.2ほど進みましたが、中身はかなり変更が有ります。Net-Ajp13-0.0.3.tar.gz変更点というか追加した実装のサマリはこんな感じ。
- プロジェクト名をAtami(熱海)に仮決定
- モジュール名をNet::Ajp13(元はNet::AJP13)に変更
- Request,Response,HttpServlet,Configなど、サーバの基礎となるクラスを追加
- 設定ファイルはconf/atami.conf。Apache風の構文
- 起動用のスクリプトをbin/atamid(元はbin/ajp13server)に変更
- mod_perlのコンテンツハンドラ互換なコンテナクラスを追加
- CGI互換なコンテナクラスを追加(当然Perl専用)
- 内部用Loggingクラスを追加
- logs/error_log, logs/access_log出力
- オンメモリでステート管理するセッションマネージャクラスを追加
- bin/atamidをバックグラウンドで実行。終了はbin/atamid -k
ちなみにエラーページはTomcatのスタイルシートをパクって、こんなのにしてみました。
一応SourceForge.jpにプロジェクトを作っておきました。プロジェクトの概要は
Atami(熱海) Application serverはPerlベースのサーブレットコンテナです。Jakarta Tomcatと同様にajp13プロトコルを使用して、Apache・IIS・iPlanet・Dominoなど一般的なWebサーバと連携して動作します。とかビミョーなのを書いてみた。MLへの参加をお待ちしておりますです。
Atami Application Serverの使い方
というわけで使い方と言うかインストールとセットアップの手順を簡単に説明。必要なモジュールは今のところSocket.pmぐらいですが、インタプリタスレッドを有効(-Dusethreads)にしてビルドしたPerl 5.8.xが必要です。インストールの手順はこれだけ$ tar zxvf Net-Ajp13-0.0.3.tar.gz $ cd Net-Ajp13-0.0.3/ $ perl Makefile.PL $ make # make installインストール先を変更する場合はMakefile.PLの引数を
$ perl Makefile.PL PREFIX=/path/to/dir等と変更します。インストールはこれだけ。あ、当然Webサーバにmod_jk等を組み込んでおく必要は有ります。
設定
設定はパッケージに添付してあるconf/atami.confで行います。構文はApache風。次の要素を適当に書換えてください
- Listen - 待ち受けるポート番号。普通は8009だけどTomcatの共存を考えて8019にしてたりします。
- ServerRoot - サーバのベースとなるディレクトリを設定。ApacheのServerRootと同じ様なもの
- MaxClients - 生成するスレッドの数。
MountPath /servlet webapp/この設定でURI /servlerはディレクトリwebappが割り当て(マウント)られます。webapp/のようにディレクトリを相対パスで指定するとServerRootからの相対パスで設定されます。このwebappディレクトリにサーブレットのクラスファイルを設置します。あとMountPathで設定したURIにリクエストを転送するように、Webサーバ側のmod_jkやmod_jk2を別途設定しておく必要が有る点に注意。じゃないとnot foundとかWebサーバ側で怒られます。
webappディレクトリに置くサーブレットのクラスファイルの例としてこんな感じ。
package webapp::MyFirstServlet; use base 'Net::Ajp13::HttpServlet'; use strict; sub do_get { my $self = shift; my $request = shift; my $response = shift; $response->content_type('text/html'); my $template = <<__HTML__; <html><body> METHOD: %s<br> URI: %s<br> QUERY: %s<br> AGENT: %s<br> </body></html> __HTML__ $response->printf($template, $request->method, $request->uri, $request->query_string, $request->header('User-Agent') ); $response->close(); } 1; __END__リクエストに関する情報は$requestオブジェクト(第2引数)、レスポンスに関する情報は$responseオブジェクト(第3引数)を使います。またQuery stringは勝手に解析するので
my $value = $request->get_parameter('key');等で個々のパラメータにアクセスできます。
セッション情報へのアクセスは
my $session = $request->session; my $name = $session->attribute('name'); $session->attribute('age', 29);みたいな感じです。
atamid(サーブレットエンジン)が起動するとMountPathディレクティブで設定したディレクトリを舐めて、設置済みのクラスのファイル名とクラス名を事前にロードします。このときクラスファイルを grep '^package ' して、実際のクラス名を調べるので、ファイル名とクラス名(package名)が異なっていても問題なく起動することができます。
半分冗談ですが、tarで固めたディレクトリをマウントする MountTarディレクティブなんてのも用意しておきました。
起動と停止
Atamiの起動と停止は添付してあるbin/atamidスクリプトを使用します。起動は$ bin/atamid -f conf/atami.conf停止は
$ bin/atamid -f conf/atami.conf -k設定ファイルの構文チェックは
$ bin/atamid -f conf/atami.conf -tです。必ず -fオプションで設定ファイルを指定する必要が有ります。
セッション管理はどーなってるの?
今実装してあるセッション管理の仕組みは、サーブレットエンジンのメモリ上でセッション情報を保持管理し、スレッド間で共有します(use thread::shared;)。セッションIDはHTTP Cookieで持たせるタイプの簡単なものです。ちなみに再起動すると消えます。これは起動/終了時にファイルとの読み込み/書き出しな処理を書いていないだけなので、すぐ解消できるでしょう。セッションIDはコンテナ側で自動生成してHTTP Cookieにセットします。今の実装だと生成されるSession IDが超適当なので、HMACなど検査可能 & 予測困難な値を生成させる必要が有りますね。あURI rewriteベースのやつはまだ実装してませんが、mod_rewriteでよろしくやってもらうと言う簡単な解決方法も有りますな。
今後の展望
恒例のToDoサラシ- ウマい煽り文句・アピールポイント・シナリオを考える
- 宣伝
- Sessionにリファレンスをセットできるように、シリアライズ処理を追加
- セッション情報の終了時ファイル書き出し & 起動時ファイル読み出し
- リソースプール関係のベースクラス開発(RDBMSのコネクションプール用)
- TomcatのTcp Session Replicationと繋ぐ
- テストの実装
- Log関係の再整理
- プラグインAPIの整備(Java ServletのFilter的なものを妄想中)
- セットアップマニュアル
- ユーザーズマニュアル
- FAQ
- Webサイト