うちのマシンは非力でcgiの起動は結構負荷がかかるので、以前からどうにかしたいなぁと思っていた。いま使っているdynamic_cacheプラグインで、負荷軽減はかなりされたんだが、それでも最初にcgiを起動してしまうので、どうにかして静的なキャッシュの仕組みを作れないかと四苦八苦してみた。
現在、サーバーの設定は.htaccessでファイルとかディレクトリがない場合に、blosxom.cgiを実行するようになっている。
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ blosxom.cgi/$1 [L,QSA]
だから、blosxomのディレクトリとdynamic_cacheのキャッシュ先を一緒にすれば、キャッシュされたファイルは次回からは直接httpdにより処理される。
ここまでは以前試してあったのだが、これだと問題が3つある。一つは設定に関することで、残りの二つはプラグインをいじらないといけない問題だ。
- rootのindex.htmlとblosxom.cgiがバッティングしてえらいことになる。
- dynamic_cacheはヘッダーも含めてキャッシュするので、キャッシュ表示の際にContent-Typesとか表示されてしまう。
- recache=allでキャッシュディレクトリ以下のすべてのファイルが消去されてしまうため、キャッシュ先をルートに設定するとblosxomのサブディレクトリ以外の画像ファイルとかも消してしまう。
1に関しては先日発見した通りに適当なディレクトリを用意してそこにRewriteするようにすればよい。うちだとこんな感じ。
DirectoryIndex index.html
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^.].*)$ .bldir/blosxom.cgi/$1 [L,QSA]
で、残りの二つはdynamic_cacheプラグインを修正して対応。2はヘッダー除いて保存するようにdynamic_cacheを書き換えた。
# キャッシュファイル出力
if ($fh->open("> $cache_dir/$cachefile")) {
$blosxom::output =~ s/^Content-Type: .*?; charset=.*?\r?\n\r?\n//;
print $fh $blosxom::output;
close $fh;
logput("SAVE ");
}
3に関しては、dynamic_cacheで使っているFile::Pathって知らなかった。
ドキュメント読んだら、消したいディレクトリとかファイルのリストのリファレンスを与えればよいらしい。
dynamic_cacheだとキャッシュ用ディレクトリを消すようになっていたので、ここを書き換えた。
# キャッシュ全クリア
# 【flavourの記述例】<input type="hidden" name="recache" value="all">
if($recache=~/all/i){
require File::Path;
my @del_dir = map {$cache_dir . "/" .$_} ("Computer", "Etc", "daily", "Food",
"trekking", "index.rss10", "index.html",
"2004", "2005", "2006",
"index.rss", "index.xml");
File::Path::rmtree(\@del_dir) and logput("CLEAR","ALL");
}
こんな感じで、今のところ静的にキャッシュされている感じだが、このせいで、taggingプラグインみたいにgetで処理するプラグインが動かなくなってしまった。
これもRewriteRuleでうまく処理できるのだろうか?
Search::Estraierを使うことを考えたほうがよいかなと思ったりもしてるが。